基本语法注意事项
-
请始终坚持===比较
JS中相等运算符有两种==和===,由于js的设计缺陷,不要使用==来比较,请始终坚持===比较。
第一种==,它会自动转换数据类型再比较,很多时候会出现诡异的结果
第二种===,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一直再比较。
ES6字符串拼接的新方式
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;//es6新写法
var oldmessage = '你好, ' + name + ', 你今年' + age + '岁了!';
- js属性
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
};
'name' in xiaoming; // true
'grade' in xiaoming; // false
'toString' in xiaoming; // true 注意in会去判断继承的属性,因为对象都继承自object 所以都会有tostring属性
所以应该这样判断
xiaoming.hasOwnProperty('toString'); // false
- 条件判断
var s = '123';
if (s.length) { // 条件计算结果为3,返回***true***
//JavaScript把null、undefined、0、NaN和空字符串''视为false,其他值一概视为true,因此上述代码条件判断的结果是true。
}
- Map和Set
1.js的对象{},就可以视作为键值对的map,但是有个**缺陷**普通对象的key必须字符串,key为数字或其他类型是个合理需求。
2.所以在ES6里面加入了新的类型Map,写法如下:
var m = new Map();
var s = new Set();
- 循环注意点
以下结果请看差异:
1.for…in因为设计问题,它遍历的是对象的属性名称,一个array也是一个对象,array的元素也视为一个属性,所以出现如下奇怪现象。
*但array自带的length属性确没有包括在内,被设计者屏蔽掉
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
alert(x); // '0', '1', '2', 'name'
}
2.for…of ES6为了避免上述不合理设计而引入
for (var x of a) {
alert(x); // 'A', 'B', 'C'
}
而最好的循环方式是使用iterable内置的forEach方法
var a=['a','b','c'];
a.forEach(function (element, index, array) {
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
alert(element);
});
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
alert(value);
});
变量作用域的坑
由于JS在函数外声明的变量(函数也视为变量)都会在全局作用域里,所以有可能会在实际开发中遇到一个大坑,全局作用域的变量名和其他库的变量名冲突,如果都有一个全局变量为var count,很有可能不恰当的时候count值被莫名其妙改成不对的值,那怎么做呢?
把自己的代码全部放入唯一的名字空间MYAPP中,会大大减少全局变量冲突的可能。
许多著名的JavaScript库都是这么干的:jQuery,YUI,underscore等等。
// 唯一的全局变量MYAPP:
var MYAPP = {};
// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函数:
MYAPP.foo = function () {
return 'foo';
};
闭包注意点
返回闭包时牢记的一点就是:**返回函数不要引用任何循环变量**,或者后续会发生变化的变量。
闭包的作用:http://blog.csdn.net/yaerfeng/article/details/7326956
下面是一个计数器
function a(){
var i=0; //这个i会一直累加,不管调用多少次,原因是b一直依赖a函数,GC不会回收i,而且i造成是个私有属性,这部是很酷么?
function b(){
alert(++i);
}
return b;
}
var c = a();
c();
数据类型
不要使用new Number()、new Boolean()、new String()创建包装对象;
用parseInt()或parseFloat()来转换任意类型到number;
用String()来转换任意类型到string,或者直接调用某个对象的toString()方法;
通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {…};
typeof操作符可以判断出number、boolean、string、function和undefined;
判断Array要使用Array.isArray(arr);
判断null请使用myVar === null;
判断某个全局变量是否存在用typeof window.myVar === ‘undefined’;
函数内部判断某个变量是否存在用typeof myVar === ‘undefined’。
面向对象
由于javascript不区分类与实例的概念,所以在创建对象的时候有些特殊性,通过原型(prototype)来实现面向对象编程。
例:
var yuanwu={
name:"yuanwu";
height:175;
run:function(){
console.log(this.name+'is run');
}
};
//现在我们想要创建一个DMC的人怎么办呢?
var dmc{
name:"dmc";
};
//通过把dmc的原型指向yuanwu来达到目的
dmc.prototype=yuanwu;
dmc.name;//输出是dmc
dmc.run();//输出是dmc is run
//或者这种写法
var dmc=Object.create(yuanwu);//Object.create
dmc.name=dmc;