1.第四章
1)执行环境+作用域
执行环境分为全局执行环境+函数执行环境。每个执行环境都有一个对应的变量对象,里面保存着相关的变量和函数。
// 参考: https://www.jianshu.com/p/7c52938915da
2)垃圾收集机制:
标记清除(进入、离开执行环境进行标记)
引用计数(清除引用数为0的数据)
2.第六章:面向对象
a)创建对象的方式
1、工厂模式
缺点是:未解决对象识别的问题
function createObj(name){
var obj = new Object();
obj.name = name;
obj.getName = function(){
return this.name;
}
return obj;
}
var obj1 = createObj('someName');
2、构造函数模式
缺点是:实例对象不能共享属性和方法
function Person(name){
this.name = name;
this.getName = function(){
return this.name;
}
}
var person = new Person('someName');
3、原型模式
缺点是:没有自己的实例属性和方法,对象的属性都是公用的,一改都改了
function Person(){}
Person.prototype.name = 'someName';
Person.prototype.getName = function(){
return this.name;
};
4、组合模式:原型模式+构造函数模式
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
return this.name;
};
var person = new Person('someName');
还有就是用对象字面量的方式改写prototype,但是会导致constructor指向Object,而不再是Persion,所以需要回指
Person.prototype = {
constructor: Person,
age: 12,
friends: ['f1', 'f2'],
getName: function(){
return this.name;
};
}
var person1 = new Person('p1');
var person1 = new Person('p2');
p1.age = 23; // 此时 p1.age: 23 p2.age: 12
p1.friends.push('f3'); // 此时 p1.friends 和 p2.friends 都是: [f1 f2 f3]
//即对简单类型的修改 会生成对应对象实例的实例属性
//对引用类型的修改 每个对象实例都是共享该数据的(原因:对象实例中保存的是引用类型数据的内存地址)
5、动态原型模式
所有信息封装到构造函数中,在构造函数中,判断某个共有属性或者方法是否存在,决定是否进行原型的修改
缺点:新建了实例后,不能再进行原型的改写
function Person(name){
this.name = name;
if(typeof this.sayName !== 'function'){
Person.prototype.sayName = function(){//只注册一次
return this.name;
};
}
}
6、寄生构造函数模式
缺点:不能使用instanceof判断实例类型
function CreateObj(name){
var obj = new Object();
obj.name = name;
obj.sepcialMethod = function(){...}
return obj;
}
//以构造函数的形式使用上面的函数,相当于改写了构造函数的返回值
//构造函数默认返回新创建的对象,有了return语句后 会返回指定的对象
//使用场景:想要改写某类型对象 使其具有特殊的方法 而又不能改变其原生构造函数的情况下
var obj = new CreateObj('name');
7、稳妥构造函数模式
缺点:不能使用instanceof判断实例类型
function CreateObj(name){
var obj = new Object();
obj.getName = function(){return name;}
return obj;
}
//稳妥对象:一般用于对数据访问有安全性限制的情况下
var obj = new CreateObj('name');//要想访问name 只能通过getName
b)继承
1、原型链继承
缺点:无法向父类构造函数传值,而且父类的实例属性会成为子类的原型属性,存在数据共享带来的问题
function Sup(age){
this.age = age;
}
Sup.prototype.method1 = function(){}
function Sub(name){
this.name = name;
}
Sub.prototype = new Sup();
2、构造函数继承
缺点:没有公用的方法和属性
function Sup(age){
this.age = age;
}
function Sub(name, age){
Sup.call(this, age)
this.name = name;
}
3、组合继承
缺点:调用2次父类的构造函数
function Sup(age){
this.age = age;
}
Sup.prototype.method1 = function(){}
function Sub(name, age){
Sup.call(this, age)//1次
this.name = name;
}
Sub.prototype = new Sup();//2次
4、原型式继承
将一个已经存在的对象作为新对象的原型对象,单纯的想要某个对象有另外一个对象的方法和属性的时候,可以使用这种方式
var obj = Object.create(prototypeObj)
5、寄生继承:懒了 没看
6、寄生组合式继承:懒了 没看
3、第12章:DOM遍历
NodeIterator + TreeWalker //深度优先
4、第22章:高级技巧
函数柯里化:将接受几个参数的函数改造成接受一个参数的函数,并返回一个包含剩余参数的函数,见代码:
//改造前
function add(x, y){ return x + y;}
add(2+3);
//改造后
function add(x){ return function(y){return x + y;}}
add(2)(3);
//柯里化的好处:延迟计算、参数复用、动态生成函数
网友评论