1.&&
&&如果左面的都为true,返回最右面的表达式的值。比如下面这种写法:
var len = undefined;
if(book) {
if(book.title) len = book.title.length;
}
可以用这种方法替代:
var len = book && book.title && book.title.length;
同理:
a = a || {}
2.简单的继承方法
function inherit(p) {
if(p == null) throw TypeError();
if(Object.create) return Object.create(p);
var t = typeof p;
if(t !== 'object' && t!== 'function')throw TypeError();
function f(){};
f.prototype = p;
return new f();
}
3.遍历属性时跳过方法和继承的属性
for(p in o) {
if(!o.hasOwnProperty(p))continue;
if(typeof o[p] === 'function')continue;
}
4.用来枚举属性的对象工具函数
5.得到类名
function classOf(o) {
if(o === null) return 'Null';
if(o === undefined) return 'Undefined';
return Object.prototype.toString.call(o).slice(8,-1)
}
6.方法调用中嵌套函数的上下文
this没有作用域的限制,嵌套的函数不会从调用它的函数中继承this。如果嵌套函数做为方法调用,其this的值指向调用它的对象,
如果嵌套函数做为函数调用,其this值是全局对象(非严格模式下)或undefined(严格模式下)。比如:
var o = {
m : function() {
var self = this;
console.log(this === o);//true
f();
function f() {
console.log(this === o);//false
console.log(self === o);//true
}
}
}
7.闭包的错误使用
如果理解了词法作用域的规则,就能很容易的理解闭包:函数定义时的作用域链到函数执行
时依然有效。关联到闭包的作用域链都是“活动的”,记住这一点非常重要。嵌套的函数不会将
作用域内的私有成员复制一份,也不会对所绑定的变量生成静态快照。
//返回一个函数组成的数组,它们的返回值是0~9
function constfuncs() {
var funcs = [];
for(var i = 0; i < 10; i++) {
funcs[i] = function(){return i};
}
return funcs;
}
var funcs = constfuncs();
funcs[5]();//返回值是?
上面这段代码创建了10个闭包,并将它们存储到了一数组中。这些闭包都是在同一个函数
调用中定义的,因此它们可以共享到变量i。当constfuncs()返回时,变量i的值是10,所有的
闭包都共享这一个值,因此,数组中的函数返回值都是同一个值。再看看下面这段代码:
//这个函数返回一个总是返回v的函数
function constfunc(v){ return function(){return v;}; }
//创建一个数组用来存储常数函数
var funcs[];
for(var i = 0; i < 10; i++) {
//相当于funcs[i] = function (i){return function() {return i;};}(i); ,i直接保存
//在constfunc的参数里了,这个时候内层的i和循环变量的i已经没关系了。相当于又多了
//一个闭包,这个闭包保存了外部的值i。这个是我理解了好久才想通的, 人太笨了没办法,
//应该没有理解错,如果有问题,欢迎指正。
funcs[i] = constfunc(i);
}
funcs[5]() //5