构造函数(constructor)——对象的模板
- 函数体内部使用了
this关键字,代表了所要生成的对象实例。 - 生成对象的时候,必须使用
new命令,过程如下。- 创建一个空对象,作为将要返回的对象实例。
- 将这个空对象的原型,指向构造函数的
prototype属性。 - 将这个空对象赋值给函数内部的
this关键字。 - 开始执行构造函数内部的代码。
原型对象(prototype)
JavaScript 规定,每个函数都有一个prototype属性,指向一个对象。
function P() {};
typeof P.prototype; // "object"
prototype => {constructor:P}
P.prototype.constructor === P; // true
修改原型对象时(比如继承和已有对象生成实例),一般要同时修改constructor属性的指向
var MyArray = function () {};
MyArray.prototype = new Array();
MyArray.prototype.constructor = MyArray;
获取实例对象obj的原型对象
obj.__proto__ // __proto__属性只有浏览器才需要部署
obj.constructor.prototype
Object.getPrototypeOf(obj)
继承
// 第一步是在子类的构造函数中,调用父类的构造函数。
function Sub(value) {
Super.call(this);
this.prop = value;
}
// 第二步,是让子类的原型指向父类的原型,这样子类就可以继承父类原型。
Sub.prototype = Object.create(Super.prototype); // new Super()
Sub.prototype.constructor = Sub;
Sub.prototype.method = '...';
多重继承 (这种模式又称为 Mixin(混入))
function M1() {
this.hello = 'hello';
}
function M2() {
this.world = 'world';
}
function S() {
M1.call(this);
M2.call(this);
}
// 继承 M1
S.prototype = Object.create(M1.prototype);
// 继承链上加入 M2
Object.assign(S.prototype, M2.prototype);
// 指定构造函数
S.prototype.constructor = S;
var s = new S();
s.hello // 'hello'
s.world // 'world'
方法区分
- 原形对象方法
prototype.func - 静态方法 构造函数上的方法
Constructor.func - 实例方法
this.func
object 静态方法
Object.create()
以这个现有的对象作为模板,生成新的实例对象,这时就可以使用Object.create()方法。
Object.create()方法的实质:
if (typeof Object.create !== 'function') {
Object.create = function (obj) {
function F() {} // 1. 新建一个空的构造函数F
F.prototype = obj; // 2. 让`F.prototype`属性指向参数对象obj
return new F(); // 3. 返回一个F的实例
};
}
所以Object.create()方法生成的新对象,动态继承了原型。在原型上添加或修改任何方法,会立刻反映在新对象之上。
var obj1 = { p: 1 };
var obj2 = Object.create(obj1);
obj1.p = 2;
obj2.p // 2
三种方式生成的新对象是等价
var obj1 = Object.create({});
var obj2 = Object.create(Object.prototype);
var obj3 = new Object();
对象的拷贝
- 确保拷贝后的对象,与原对象具有同样的原型。
- 确保拷贝后的对象,与原对象具有同样的实例属性。
function copyObject(orig) {
return Object.create(
Object.getPrototypeOf(orig),
Object.getOwnPropertyDescriptors(orig)
);
}
Object.prototype.hasOwnProperty()
判断某个属性定义在对象自身,还是定义在原型链上。
this
-
构造函数中表示实例对象;
-
全局环境表示windows对象
-
对象方法this指向当前一层的对象,赋值给另个对象会改变this指向,一般会出现如下
- 嵌套
// 属性嵌套 var a = { b: { m: function() { console.log(this.p); }, p: 'Hello', } }; (a.b).m() // 等同于 b.m() // 方法嵌套 var o = { f1: function () { console.log(this); var f2 = function () { console.log(this); }(); } } o.f1() // Object // Window- 回调函数 (回调函数中的this往往会改变指向,最好避免使用)
var o = new Object(); o.f = function () { console.log(this === o); } // jQuery 的写法 $('#button').on('click', o.f); // f方法是在按钮对象的环境中被调用的
this绑定
bind()方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。
apply()方法改变this指向,然后接收一个数组作为函数执行时的参数再调用该函数
call()方法指定函数内部this的指向(即函数执行时所在的作用域),接收func.call(thisValue, arg1, arg2, ...),调用该函数。