一般一个人一段时间内专注于一门语言开发。学的语言太多,搞的太杂不是好事,因为语言本身的语法不相同或南辕北辙(如: for (let checkModelListUnit in checkModelList) )。对公司领导来说希望你啥都做.对代码质量来说,同时做的越多,出错的可能越大。大公司通常是专人做专事,小公司最好在一段时间内以一种语言开发为主。不学习容易被淘汰,杂而不精容易影响开发质量和效率。
1.JavaScript 拥有动态类型。JavaScript的变量类型可以随意切换
若你给他赋值为数字,再次给它一个字符串,它以最后一次的类型为准是字符类型。而Object C要严格的多,这样它会报错的
length = 6 length = 'ddd' var x = 5 + 6;var y = x * 10; // document.write(16 + "Volvo") document.write(length)
2.JavaScript的对象十分简洁,用花括号括起来的一堆键值对。和Object C 的字典稍有不同,Object C的字典的值必须是字符串或对象,并且数字不属于对象。而JavaScript却把数字认为是number类型可以当键值对的值。若Object C进行json解析不进行对象转换,直接把number当字符串使用很容易闪退。
可以说 “JavaScript 对象是变量的容器”。
但是,我们通常认为 “JavaScript 对象是键值对的容器”。
键值对通常写法为 name : value (键与值以冒号分割)。
键值对在 JavaScript 对象通常称为 对象属性。
Object C的对象不是键值对的容器而是变量的容器。因为它的类通常放在.h文件中先声明属性(变量),在.m文件中实现它的方法,在方法中操作其它的对象,然后在其它方法中根据类生成对象。而JavaScript完全简化为一行代码搞定了。😊
3.JavaScript的Number(var x= new Number;),number是类型的值((typeof(3) == ‘number’))
4.JavaScript的函数需要用function修饰,Object C不需要,但是要声明返回类型(-(void)或+ (UIImage *))。
5.如果您把值赋给尚未声明的变量,该变量将被自动作为 window 的一个属性。Object C的变量必须显示性的声明。
var var1 = 1; // 不可配置全局属性 var2 = 2; // 没有使用 var 声明,可配置全局属性 console.log(this.var1); // 1 console.log(window.var1); // 1 console.log(window.var2); // 2 delete var1; // false 无法删除 console.log(var1); //1 delete var2; console.log(delete var2); // true console.log(var2); // 已经删除 报错变量未定义
6.在 JavaScript 中, 对象和函数同样也是变量。
在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。
JavaScript 函数作用域: 作用域在函数内修改。
Object C的类是相当于c语言的结构体的增强版,在其它类的方法中根据类生成对象。JavaScript完全简化了它的实现。
7.在函数中没有用var声明变量但是赋值过,在外部也没有声明,在外面直接调用它会报错,用window.访问该变量会报undefined
function myFunction2(name,job){
return ("Welcome " + name + ", the " + job);
carName = “Volvo”;
}
document.getElementById(“demo”).innerHTML=myFunction2(‘I’, ‘Jhone’);
// document.getElementById(“demo”).innerHTML=carName;
// alert(carName);//Uncaught ReferenceError ReferenceError: carName is not defined
alert(window.carName);//undefined
8.在 JavaScript 中,=== 为绝对相等,即数据类型与值都必须相等
9.JavaScript 中的模板字符串是一种方便的字符串语法,允许你在字符串中嵌入表达式和变量。
模板字符串使用反引号 作为字符串的定界符分隔的字面量。 模板字面量是用反引号()分隔的字面量,允许多行字符串、带嵌入表达式的字符串插值和一种叫带标签的模板的特殊结构。
英文模式下+数字键盘1左边的键。就可以直接打出反引号`
10.在JavaScript中,let(const)是一个关键字,用于声明一个块级作用域的局部变量。块级作用域是由一对花括号 {} 界定的任何代码块,例如一个函数、一个循环体或者一个条件语句块。
块级作用域:let(const)声明的变量仅在声明它们的块或子块中可用。
不存在变量提升:(相反的var声明的变量会被提升到其包含作用域的顶部),const与let一样,const声明的变量不会被提升到其包含作用域的顶部。在声明之前引用let(const)变量会导致引用错误。
暂时性死区(Temporal Dead Zone,TDZ):let(const)声明的变量存在于从块的开始到声明之间的暂时性死区中。在TDZ中,访问这些变量会引发错误。
只读属性:const声明的变量不能重新赋值。这意味着一旦一个变量被const声明,它的值就不可改变。
对于对象和数组:虽然const声明的对象和数组本身不能重新赋值,但是对象的属性和数组的元素可以修改。
重复声明限制:在同一个作用域内,let(const)不允许重复声明同一个变量,而var可以。
JavaScript 中,var 关键字定义的变量可以在使用后声明,也就是变量可以先使用再声明
let 关键字定义的变量则不可以在使用后声明,也就是变量需要先声明再使用。
const声明的常量必须初始化,而let声明的变量不用
const 定义常量的值不能通过再赋值修改,也不能再次声明。而 let 定义的变量值可以修改。
11.如果数字与字符串相加,返回字符串
12.在JavaScript中,数组可以越界访问只是值为空。Object C数组越界访问就会crash,并且抛异常try catch也没有用,app直接退出,所以它很少用try catch。同时Object C主要保证不抛异常,要进行各种防范,一旦抛异常一般神仙也难救。也不是所有的try catch都没有用,我见到一个UILart弹窗,有时候app启动时弹窗时闪退,用try catch就避免了闪退,这样的很少。Object C一直是各种判断尽量避免闪退,解决闪退的根本方法除了纠正各种错误的逻辑,其次是尽量进行各种判断避免抛异常。逻辑错误是我们尽量避免的,但是任何人都很难避免逻辑错误引起抛异常。但是我们可以通过各种判断来避免抛异常。而python和js要健壮的多,捕获异常就能避免闪退,而app基本上捕获到异常它该死还是死。语言不同决定了它的健壮性不同,对程序猿的要求也不同。
cars=["BMW","Volvo","Saab","Ford"]; var i=0; while (cars[i]) { document.write(cars[i] + "<br>"); i++; }
13.可以对 JavaScript 语句进行标记。
如需标记 JavaScript 语句,请在语句之前加上冒号:
通过标签引用,break 语句可用于跳出任何 JavaScript 代码块:
cars=["BMW","Volvo","Saab","Ford"]; list: { document.write(cars[0] + "<br>"); document.write(cars[1] + "<br>"); document.write(cars[2] + "<br>"); break list; document.write(cars[3] + "<br>"); document.write(cars[4] + "<br>"); document.write(cars[5] + "<br>"); }
14.在 JavaScript 中 null 表示 “什么都没有”。
你可以设置为 null 来清空对象:
var person = null; // 值为 null(空), 但类型为对象
你可以设置为 undefined 来清空对象:
var person = undefined; // 值为 undefined, 类型为 undefined
null 和 undefined 的值相等,但类型不等:
typeof undefined // undefinedtypeof null // objectnull === undefined // falsenull == undefined // true片
Object C没有undefined关键词,空为nil,只有对象类型才和nil比较,数字类型不和nil比较。
15.在 JavaScript 中有 6 种不同的数据类型:
string
number
boolean
object
function
symbol
3 种对象类型:
Object
Date
Array
2 个不包含任何值的数据类型:
null
undefined
而Object C的类型要多的多。
16.constructor 属性
constructor 属性返回所有 JavaScript 变量的构造函数。
**[1,2,3,4].constructor // 返回函数 Array() { [native code] } {name:'John', age:34}.constructor // 返回函数 Object() { [native code] }**
如果对象是 JavaScript Array 或 JavaScript Date ,我们就无法通过 typeof 来判断他们的类型,因为都是 返回 object。
可以使用 constructor 属性来查看对象是否为数组 (包含字符串 “Array”):
function isArray(myArray) { return myArray.constructor.toString().indexOf("Array") > -1; }
17.在JavaScript中,NaN(Not a Number)是一个特殊的数值,它表示一个本来应该返回数值的操作数未返回数值的情况。NaN有几个独特的属性:
NaN不等于任何值,包括它自己。
NaN的类型是number。
因此,判断一个值是否为NaN不能简单地使用相等运算符(===),因为NaN === NaN的结果是false。相反,您可以使用Number.isNaN()函数或全局isNaN()函数。
Number.isNaN()不会对非数值类型的值进行类型转换,因此它更安全,不会因为隐式类型转换而产生意外的结果。
isNaN()会进行类型转换,这意味着它可能会对非数值类型的值返回true,即使这些值在逻辑上不是NaN。
18.当 JavaScript 尝试操作一个 “错误” 的数据类型时,会自动转换为 “正确” 的数据类型。
5 + null // 返回 5 null 转换为 0"5" + null // 返回"5null" null 转换为 "null" "5" + 1 // 返回 "51" 1 转换为 "1" "5" - 1 // 返回 4 "5" 转换为 5
19.当你尝试输出一个对象或一个变量时 JavaScript 会自动调用变量的 toString() 方法
document.getElementById("demo").innerHTML = myVar; myVar = {name:"Fjohn"} // toString 转换为 "[object Object]" myVar = [1,2,3,4] // toString 转换为 "1,2,3,4" myVar = new Date() // toString 转换为 "Fri Jul 18 2014 09:08:55 GMT+0200" myVar = 123 // toString 转换为 "123" myVar = true // toString 转换为 "true" myVar = false // toString 转换为 "false"
20。JavaScript 声明提升
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
JavaScript 只有声明的变量会提升,初始化的不会。
21.在常规的比较中,数据类型是被忽略的,以下 if 条件语句返回 true:
var x = 10; var y = "10"; if (x == y)
在严格的比较运算中,=== 为恒等计算符,同时检查表达式的值与类型,以下 if 条件语句返回 false:
var x = 10;var y = "10";if (x === y)
这种错误经常会在 switch 语句中出现,switch 语句会使用恒等计算符(===)进行比较:
JavaScript 允许我们在字符串中使用断行语句:
var x = "Hello World!";
字符串断行需要使用反斜杠(),如下所示:
var x = "Hello \ World!";
以下实例中,if 语句失去方法体,原 if 语句的方法体作为独立的代码块被执行,导致错误的输出结果。
由于分号使用错误,if 语句中的代码块就一定会执行:
if (x == 19);{ // code block }
JavaScript 默认是在一行的末尾自动结束。
以下两个实例返回结果是一样的(一个有分号一个没有):
function myFunction(a) { var power = 10 return a * power}
function myFunction(a) { var power = 10; return a * power;}
JavaScript 也可以使用多行来表示一个语句,也就是说一个语句是可以分行的。
以下实例返回相同的结果:
function myFunction(a) { var power = 10; return a * power;}
但是,以下实例结果会返回 undefined:
function myFunction(a) { var power = 10; return a * power; }
在 JavaScript 中,分号是可选的 。
最好别写这些奇葩的代码,正常写就行,别省去分号和乱换行,不作死不会死。为了简洁而制造bug是不可取的。
许多程序语言都允许使用名字来作为数组的索引。
使用名字来作为索引的数组称为关联数组(或哈希)。
在 JavaScript 中, 对象 使用 名字作为索引。
如果你使用名字作为索引,当访问数组时,JavaScript 会把数组重新定义为标准对象。
执行这样操作后,数组的方法及属性将不能再使用,否则会产生错误:
var person = []; person["firstName"] = "John"; person["lastName"] = "Doe"; person["age"] = 46;var x = person.length; // person.length 返回 0var y = person[0]; // person[0] 返回 undefined
数组最后一个值的后面添加逗号虽然语法没有问题,但是在不同的浏览器可能得到不同的结果。
var colors = [5, 6, 7,]; //这样数组的长度可能为3 也可能为4。
定义对象,最后不能添加逗号
websites = {site:"菜鸟教程", url:"www.runoob.com", like:460,}
Undefined 不是 Null
在 JavaScript 中, null 用于对象, undefined 用于变量,属性和方法。
对象只有被定义才有可能为 null,否则为 undefined。
如果我们想测试对象是否存在,在对象还没定义时将会抛出一个错误。
错误的使用方式:
if (myObj !== null && typeof myObj !== "undefined")
正确的方式是我们需要先使用 typeof 来检测对象是否已定义:
if (typeof myObj !== "undefined" && myObj !== null)
在每个代码块中 JavaScript 不会创建一个新的作用域,一般各个代码块的作用域都是全局的。
以下代码的的变量 i 返回 10,而不是 undefined:
for (var i = 0; i < 10; i++) { // some code } return i;
Object C这样写编译不通过。可见它的语法比js严格的多, js的约束很低。
22.JavaScript的函数可以有的情况返回值,有时不返回值。这在Object C中会编译报错。
function validateForm() { var x=document.forms["myForm"]["fname"].value; if (x==null || x=="") { alert("姓必须填写"); return false; } }
23.JavaScript 不是类型语言。与许多其他编程语言不同,JavaScript 不定义不同类型的数字,比如整数、短、长、浮点等等。
在JavaScript中,数字不分为整数类型和浮点型类型,所有的数字都是由 浮点型类型。
如果前缀为 0,则 JavaScript 会把数值常量解释为八进制数,如果前缀为 0 和 “x”,则解释为十六进制数
除以0产生无限:
24.js可以在遍历数组时删除数组元素,一般OC都是先标记要删除的元素地址,然后按对象地址删除数组元素。
这个是从前向后访问,注意删除后要i-1:
for (let i=0; i<list.length; i++) { if (!list[i]) { list.splice(i,1); i--; } }
这个是从后向前访问:
// 从后向前遍历,避免索引变化导致的问题 for (let i = list.length - 1; i >= 0; i--) { // 假设我们想要删除所有的 'banana' if (list[i] === 'banana') { list.splice(i, 1); } }
25.在 JavaScript 中,几乎所有的对象都有一个原型(prototype)。原型是对象继承属性和方法的地方。在 JavaScript 中,原型链是实现继承的主要机制。
原型链的工作方式是,当你访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 会沿着原型链向上查找,直到找到对应的属性或方法,或者到达原型链的顶端(通常是 Object.prototype),如果还没有找到,则会返回 undefined。
这种原型继承模型是 JavaScript 的一个独特特性,它允许对象继承其他对象的属性和方法,从而实现代码的复用和扩展。
通过prototype可以给类添加新方法
function Person(name, age) { this.name = name; this.age = age; } // Person.prototype 是一个对象,它将包含所有 Person 实例共享的属性和方法 Person.prototype.greet = function() { console.log(`Hello, my name is ${this.name} and I am${this.age} years old.`); }; const person1 = new Person("Alice", 30); person1.greet(); // Hello, my name is Alice and I am 30 years old. const person2 = new Person("Bob", 25); person2.greet(); // Hello, my name is Bob and I am 25 years old.
不过js使用类的频率并不高
26.在 JavaScript 中,let in 和 let of 是两种不同的语法结构,用于不同的目的。
let in 通常用于遍历对象的属性。它允许您访问对象属性的名称和值。
注意:使用 let in 时,需要检查 hasOwnProperty 方法,以确保属性确实存在于对象自身,而不是其原型链上。
const obj = { first: 'John', last: 'Doe' }; for (let key in obj) { if (obj.hasOwnProperty(key)) { console.log(`Key: ${key}, Value:${obj[key]}`); } }
let of 是ES6(ECMAScript 2015)引入的,用于遍历可迭代对象(如数组)的元素。
let of 不需要使用 hasOwnProperty 检查,因为它只遍历数组本身的元素。
const arr = [10, 20, 30]; for (let value of arr) { console.log(value); // 输出: 10, 20, 30 }
这两个循环结构的主要区别在于它们分别用于不同类型的数据结构:let in 用于对象,而 let of 用于数组和其他可迭代对象。
选择使用哪一个取决于您的具体需求和正在处理的数据类型。如果您正在处理一个对象,并且需要访问其属性,那么 let in 会是合适的选择。如果您正在处理一个数组或任何可迭代的对象,并且需要访问其元素,那么 let of 会更适合。
千万别把let in 遍历普通数组,不然会错的十万八千里。这和Python和Object C完全不同,最容易搞混。
for (let checkModelListUnit in checkModelList) { console.log('checkModelListUnit:',checkModelListUnit, location_name);
打印的不是数组元素而是数组下标:
checkModelListUnit: 0 西美岸中心 checkModelListUnit: 1 西美岸中心 checkModelListUnit: 2 西美岸中心 checkModelListUnit: 3 西美岸中心 checkModelListUnit: 4 西美岸中心 checkModelListUnit: 5 西美岸中心 checkModelListUnit: 6 西美岸中心 checkModelListUnit: 7 西美岸中心 checkModelListUnit: 8 西美岸中心 checkModelListUnit: 9 西美岸中心 checkModelListUnit: 10 西美岸中心 checkModelListUnit: 11 西美岸中心
正确的代码:
for (let i = 0; i < checkModelList.length; i++) { let checkModelListUnit = checkModelList[i]; console.log('checkModelListUnit:',checkModelListUnit, location_name, typeof checkModelListUnit );
或
for (let checkModelListUnit of checkModelList) { console.log('checkModelListUnit:',checkModelListUnit, location_name);
打印的是正常的数据元素:
checkModelListUnit: { check_details: { location_name: '西美岸中心', location_type: '交通', lnglat: '120.04264293293733|30.291476922227535' } } 西美岸中心