JavaScript语言精粹(重读四)
2017-01-05 本文已影响21人
纸简书生
继承
js是一门弱类型语言,不需要类型转换。对象继承关系变得无关紧要。对于一个对象来说重要的是能做什么而不是从哪里来。在基于类的语言中,对象是类的实例,并且类可以从另一个类中继承。而js是一门基于原型的语言。这就一意味着对象直接从其他对象继承。
伪类
没有直接让对象从其他对象继承,而是插入了一个多余的间接层:通过构造器函数产生对象。
- 从函数说起
当一个函数对象被创建时,function构造器产生的函数对象会运行类似如下代码:this.prototype = {constructor: this}
这句话意思就是给函数对象添加一个prototype的属性,属性是一个对象。这个对象有一个属性constructor,值是自己。说起来有点绕。看代码就懂了。这个prototype对象就是存放继承特性的地方。并且每个函数都会得到一个prototype对象。
当用new前缀去调用一个函数的时候,函数执行方式会改变。如果用new运算符是一个方法而不是一个运算符。可能会这样执行:
Function.method('new', function()){
// 创建一个新对象,这个对象继承自构造函数的原型对象
var that = Object.create(this.prototype);
// 调用构造器函数,绑定this到新对象上。
var other = this.apply(that, arguments)j;
return (typeof other === "object" && other) || that;
});
现在定义一个构造器并扩充它的原型:
var Mammal = function(name) {
this.name = name;
};
Mammal.prototype.get_name = function() {
return this.name;
};
Mamal.prototype.says = function() {
return this.saying || '';
};
构造一个实例:
var myMamal = new Mamal('mamal');
var name = myMamal.get_name();
构造伪类来继承Mammal,通过定义它的constructor函数并替换它的prototype实现
var Cat = function(name) {
this.name = name;
this.saying = 'meow';
};
Cat.prototype = new Mammal();
//扩充新原型对象
Cat.prototype.test = function() {
return 'test';
}
// 使用
var myCat = new Cat('cat');
var says = myCat.says();
通过如上代码大致就能明白什么是伪类模式了。
关于伪类需要明白:
- 构造器怎么写
- 如何继承
- 如何使用
对象说明符
类似于外部参数的概念。只要外部参数正确就不用在乎参数顺序。
有时候构造函数需要接受一大串的参数,通过对象说明符则不用去记住参数顺序。
比如:
var myObject = maker(f, l, m, c,s)
;
var myObject = maker({first: f, middle: m, last: l, state: s, city: c})
原型
首先用对象字面量构造一个对象。
var myMammal = {
name : 'mammal',
get_name : function () {
return this.name;
},
says : function () {
return this.saying || '';
}
}
然后通过Object.create
方法构造出更多的实例。
var myCat = Object.create(myMammal);
myCat.name = "mycat";
myCat.saying = 'miao';
myCat.test = function () {
myCat.get_name = function () {
return 'this test';
};
}
这是一种差异化继承。其实和上面的函数继承类似。
函数化
通过函数化解决私有变量的问题。这里有一个比较牛逼的名字叫应用模块模式。具体步骤如下:
- 创建一个对象:
- 1.1 对面字面量
- 1.2 通过new调用构造函数
- 1.3 使用
Object.create()
- 1.4 调用一个返回对象的函数
- 有选择的定义私有变量和方法。
- 给这个对象扩充方法,扩充的方法有权访问这些参数
- 返回新对象。
例子
var mamal = function (spec) {
var that = {};// 这里定义私有变量
that.get_name = function () {
return 'name';
}
that.get_age = function () {
return 12;
}
return that;
}
模板抽象
var constructor = function (spec, my) {
var that;//一些私有变量
my = my || {};// my,用于接受公有参数,共享容器
that = {};//新对象
that.addFunc = function () {
}// 访问的方法
}