- 创建对象的几种方法
- 原型、构造函数、实例、原型链
- instanceof 的原理
- new 运算符
创建对象的几种方法
// 第一种方式:字面量
var o1 = { name: "o1" };
var o2 = new Object({ name: "o2" });
// 第二种方式:构造函数
var M = function (name) {
this.name = name;
};
var o3 = new M("o3");
// 第三种方式:Object.create
var p = { name: "p" };
var o4 = Object.create(p);
console.log(o1); // { name: 'o1' }
console.log(o2); // { name: 'o2' }
console.log(o3); // M { name: 'o3' }
console.log(o4); // {}
原型、构造函数、实例、原型链
对象是函数创建的,而函数却又是一种对象。也是属性的集合,可以对函数进行自定义属性。
每个函数都有一个属性叫做 prototype。
这个 prototype 的属性值是一个对象,默认的只有一个叫做 constructor 的属性,指向这个函数本身。
var Fn = function () {
this.name = "WuChenDi";
this.old = 23;
};
var f1 = new Fn();
console.log(f1); // Fn { name: 'WuChenDi', old: 23 }
console.log(Fn);
console.log(Fn.prototype);
console.log(f1.__proto__ === Fn.prototype); // true
console.log(Fn.prototype.constructor === Fn); // true
从上图可以看到对象的原型,指向构造函数的 prototype 属性。
f1.proto指向构造函数的 prototype 属性,就是对象的原型。所以 f1.proto === Fn.prototype 为 true
prototype 的属性值是一个对象,默认的只有一个叫做 constructor 的属性,指向这个函数本身。
proto就是指向构造函数的 prototype 属性,Fn.prototype 就是对象的原型
即,每个由构造函数创建的对象都有一个proto属性,指向创建该对象的函数的 prototype。
var 对象名 = new 函数名()
对象名.__proto__=== 函数名.prototype
instanceof
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
// 第一种方式:字面量
var o1 = { name: "o1" };
var o2 = new Object({ name: "o2" });
// 第二种方式:构造函数
var M = function (name) {
this.name = name;
};
var o3 = new M("o3");
// 第三种方式:Object.create
var p = { name: "p" };
var o4 = Object.create(p);
console.log(o3 instanceof M); // true
console.log(o3 instanceof Object); // true
console.log(o3.__proto__ === M.prototype); // true
console.log(M.prototype.__proto__ === Object.prototype); // true
console.log(o3.__proto__.constructor === M); // true
new 运算符
- 一个新对象被创建。他继承自foo.prototype
- 构造函数 foo 被执行。执行的时候,相应的传参会被传入,同时上下文 (this) 会被指定为这个新实例。 new foo 等同于 new foo(), 只能用在不传递如何参数的情况
- 如果构造函数返回一个 “对象” ,那么这个对象会取代整个 new 出来的结果。如果构造函数没有返回对象,那么 new 出来的结果为步骤1创建的对象 ```javascript // 第一种方式:字面量 var o1 = { name: “o1” }; var o2 = new Object({ name: “o2” });
// 第二种方式:构造函数 var M = function (name) { this.name = name; }; var o3 = new M(“o3”);
// 第三种方式:Object.create var p = { name: “p” }; var o4 = Object.create(p);
M.prototype.say = function () { console.log(“say hi”); };
var o5 = new M(“o5”);
var new2 = function (func) { var o = Object.create(func.prototype); var k = func.call(o); if (typeof k === “object”) { return k; } else { return o; } };
console.log((o6 = new2(M))); // M { name: undefined } console.log(o6 instanceof M); // true console.log(o6 instanceof Object); // true console.log(o6.proto.constructor === M); // true
M.prototype.walk = function () { console.log(“walk”); };
o6.walk(); // walk o3.walk(); // walk
常问
JS 的 new 操作符做了哪些事情?
new 操作符新建了一个空对象,这个对象原型指向构造函数的 prototype,执行构造函数后返回这个对象。