今天看了js秘密花园的对象和函数这一块,做个笔记总结和回顾一下。
对象:
1.定义:js中的一切变量皆对象,除了undefined和null。连数字字面量都是对象(object类型和对象不是一个东西0 0)
2.属性:通过obj[attr]或者obj.attr进行访问
用delete操作符进行删除操作(ex:delete obj.attr)
prototype:
每个对象都有的属性,常用于对象的继承。将一个对象的prototype指向另外一个对象,就可以访问该对象的属性。如果把prototype指向一个原子(?)类型,这个操作就会被忽略。但是当继承链太长的时候,查找属性的代价就比较高(用for in 实现对一个对象的属性排查,会访问这个对象的每一个属性)。
函数:
函数也是对象,函数名是指向函数的指针。在js中,函数和变量的声明会被解析(hoist),所以变量定义在定义前被使用也是没关系的。
提到函数主要涉及着几个方面的问题:
1.this指针 2.作为工厂模式使用 3.作为构造函数模式使用 4.闭包
1.this指针的5种情况
function foo(){ function test(){...};};
1.如果直接使用foo(); 函数的this指针指向全局对象,在浏览器中是window。
2.如果是obj.foo(),那么this指针指向当前使用的对象obj
3.foo.apply(obj, [argument]) || foo.call(obj, arg[0], arg[1], ...) || foo.bind(obj,arg[0],arg[1],...)。强制改变this指针的指向
4.直接使用this,指向全局变量
5.用new foo(),变成构造函数,this指针指向刚刚创造的对象
有个经常错的地方,this指针是不能隐式传递的,所以test()的this指针指向的是全局对象.常用的传递this指针给test的方法:
function foo(){ var that = this; function test(){ that….};}
2.作为工厂模式的时候,是这样的:
function foo(){var a = new obj(); return a;}
这样通过调用foo()就可以获得相同的a元素,相当于一个工厂一样
3.一般函数和new操作符一起使用的时候,就变成了构造函数。有两种情况:
function foo1(){return 2;}
function foo2(){return {a:xx,b:xx};};
var a = new foo1(),
b = new foo2()
对于a,返回的是一个foo1对象;对于b,返回的是return中的对象
4.我认为,闭包的设计主要是为了能够让外界环境访问函数内部的变量,相当于公有函数。不过过多的闭包可能会导致内存泄露,因为闭包时常保存对内部环境变量的引用,导致内部变量不能及时销毁。
for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
这个是很常见的错误,由于settimeout保存的是对于i的引用,在settimeout调用的时候,i已经变成了10,因此最后打印出来的都是10。可以改成:
for(var i = 0; i < 10; i++) {
(setTimeout(function(e) {
console.log(e);
}, 1000))(i);
}
或者
for(var i = 0; i < 10; i++) {
setTimeout((function(e) {
console.log(e);
})(i), 1000);
}