• 创建对象的几种方法
  • 原型、构造函数、实例、原型链
  • instanceof 的原理
  • new 运算符

创建对象的几种方法

  1. // 第一种方式:字面量
  2. var o1 = { name: "o1" };
  3. var o2 = new Object({ name: "o2" });
  4. // 第二种方式:构造函数
  5. var M = function (name) {
  6. this.name = name;
  7. };
  8. var o3 = new M("o3");
  9. // 第三种方式:Object.create
  10. var p = { name: "p" };
  11. var o4 = Object.create(p);
  12. console.log(o1); // { name: 'o1' }
  13. console.log(o2); // { name: 'o2' }
  14. console.log(o3); // M { name: 'o3' }
  15. console.log(o4); // {}

原型、构造函数、实例、原型链

面试-原型链.png

对象是函数创建的,而函数却又是一种对象。也是属性的集合,可以对函数进行自定义属性。
每个函数都有一个属性叫做 prototype。
这个 prototype 的属性值是一个对象,默认的只有一个叫做 constructor 的属性,指向这个函数本身。

  1. var Fn = function () {
  2. this.name = "WuChenDi";
  3. this.old = 23;
  4. };
  5. var f1 = new Fn();
  6. console.log(f1); // Fn { name: 'WuChenDi', old: 23 } 
  7. console.log(Fn);
  8. console.log(Fn.prototype);
  9. console.log(f1.__proto__ === Fn.prototype); // true
  10. console.log(Fn.prototype.constructor === Fn); // true

面试-原型链-原型与原型链.png

从上图可以看到对象的原型,指向构造函数的 prototype 属性。
f1.proto指向构造函数的 prototype 属性,就是对象的原型。所以 f1.proto === Fn.prototype 为 true
prototype 的属性值是一个对象,默认的只有一个叫做 constructor 的属性,指向这个函数本身。
proto就是指向构造函数的 prototype 属性,Fn.prototype 就是对象的原型
即,每个由构造函数创建的对象都有一个proto属性,指向创建该对象的函数的 prototype。

  1. var 对象名 = new 函数名()
  2. 对象名.__proto__=== 函数名.prototype

instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

面试-原型链-instanceof.png

  1. // 第一种方式:字面量
  2. var o1 = { name: "o1" };
  3. var o2 = new Object({ name: "o2" });
  4. // 第二种方式:构造函数
  5. var M = function (name) {
  6. this.name = name;
  7. };
  8. var o3 = new M("o3");
  9. // 第三种方式:Object.create
  10. var p = { name: "p" };
  11. var o4 = Object.create(p);
  12. console.log(o3 instanceof M); // true
  13. console.log(o3 instanceof Object); // true
  14. console.log(o3.__proto__ === M.prototype); // true
  15. console.log(M.prototype.__proto__ === Object.prototype); // true
  16. 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,执行构造函数后返回这个对象。