对象都是函数创建出来

创建对象的不同方式

  1. // 语法糖
  2. var obj = {}
  3. var array = [1,2,3]
  4. function Foo() {}
  5. // 等价于
  6. new Object()
  7. new Array()
  8. new Function()

对象(obj、array、function)都是属性集合

  1. var obj = { a: 1 }
  2. console.log(obj.a) // 1
  3. var array = [1,2]
  4. console.log(array.length) // 2
  5. var foo = function(a, b, c) {
  6. return a + b + c
  7. }
  8. console.log(foo.length) // 3

proto_ _和 prototype 的关系

结论:每个对象都有一个 proto,每个函数都有一个 prototype。

关系:每个对象的 proto 指向创建该对象的函数的 prototype。

xxx.prototype 和 xxx 关系:xxx.prototype.constructor 指向 xxx

  1. function Foo() {}
  2. var f = new Foo()
  3. console.log(f.__proto__ === Foo.prototype) // true

181509180812624.png

Object、Date、Boolean、Array、String 等这些内置函数也是对象(函数),它们是由 Function 创建出来的。

Function 也是对象,它是由自身创建的。

  1. // 结论
  2. Object.__proto__ === Function.prototype // true
  3. Array.__proto__ === Function.prototype // true
  4. String.__proto__ === Function.prototype // true
  5. Boolean.__proto__ === Function.prototype // true
  6. // 奇怪结论
  7. Function.__proto__ === Function.prototype // true


proto 和 prototype 指向的对象都是 Object 创建出来的,伦理说所有的 typeof xxx.prototype 都是 object 但是 typeof Function.prototype 是 function。

Object.prototype 也是一个对象,但是它的 proto 指向 null ,这一点一定要切记。

  1. function Foo() {}
  2. typeof Foo.prototype // object
  3. typeof Function.prototype // function

181512068463597.png

instanceof 操作符

判断规则:

第一个变量是一个对象,第二个变量是函数。
对象沿着 proto 寻找同时函数沿着 prototype 寻找,如果两条线能找到同一个引用,既同一个对象则返回 true 否则返回 false。

  1. // 看似很混乱,其实都是 true
  2. Object instanceof Function // true
  3. Function instanceof Object // true
  4. Function instanceof Function // true

完整版关系

javascript 原型和原型链 - 图3

最后

proto 和 prototype 指向的对象就是原型。

访问一个对象的属性时,先在对象的基本属性中查找,如果没有,再沿着 proto 这条链上找,这就是原型链。

  1. function Foo() {}
  2. var f1 = new Foo()
  3. f1.a = 10
  4. Foo.prototype.a = 100
  5. Foo.prototype.b = 200
  6. console.log(f1.a) // 10
  7. console.log(f1.b) // 200

参考:

[1] 深入了解 javascript 原型和闭包系列 链接