# JavaScript 原型

# proto 和 prototype

__proto__

每个JavaScript对象一定对应一个原型对象,并从原型对象继承属性和方法。

对象的__proto__属性对应的值就是它所对应的构造函数的原型对象

var obj1 = {};
obj1.__proto__ == Object.prototype;  //true
obj1.constructor == Object;  //true
obj1.prototype  //没有这个属性 只有函数才有prototype属性

prototype

prototype属性,不像每个对象都有__proto__属性来标识自己所继承的原型,只有函数才有prototype属性

为什么只有函数才有prototype属性?

因为当初设计JavaScript的时候使用prototype来模拟类,进而实现继承。 当创建函数时,JavaScript会为这个函数自动添加prototype属性,值值是一个有 constructor属性的对象,不是空对象。而一旦你把这个函数当作构造函数(constructor)调用(即通过new关键字调用),那么JavaScript就会帮你创建该构造函数的实例,实例继承构造函数prototype的所有属性和方法(实例通过设置自己的__proto__指向其构造函数的prototype来实现这种继承)

function foo() {}

foo.prototype
{
  constructor: foo()
  __proto__: Object
}

foo.__proto__ == Function.prototype;  //true
foo.__proto__ == foo.constructor.prototype;  //true
foo.constructor == Function; //true
foo.constructor.prototype == Function.prototype;  //true

foo.prototype.constructor == foo;  //true
foo.__proto__.__proto__ == Object.prototype; //true

# Function and Object

JavaScript是单继承的,Object.prototype是原型链的顶端

  • Object本身是构造函数,继承了Function.prototype;
  • Function也是对象,继承了Object.prototype

所以:

Object instanceof Function;  // true
Function instanceof Object;  // true

js-001

# OO练习

var a = new Object();
a.param = 123;

function foo(){
  get = function(){
    console.log(1);
  };
  return this;
}

foo.get = function(){
  console.log(2);
};

foo.prototype.get = function(){
  console.log(3);
};

var get = function(){
  console.log(4);
};

function get(){
  console.log(5);
}

foo.get();  
// => 2 实际上是在foo上添加了get方法,foo是函数,同时也是对象,所以可以添加方法

get();
// => 4 函数声明提升,后面在运行时由console.log(4);覆盖

foo().get();  
// => 1  实际上是给window上声明了一个get方法

get();
// => 1 被console.log(1);覆盖

new foo.get();
// => 2 使用的是foo.get的属性值

new foo().get();
// => 3 继承原型链上的3

new new foo().get();
// => 3 继承原型链上的3
陕ICP备20004732号-3