JavaScript笔记:原型和原型链,继承

JavaScript笔记:原型和原型链

    • 定义:
    • prototype 和__proto__
    • 原型继承 圣杯模式

定义:

原型是function对象的的一个属性,它定义了由构造函数创建的的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。

Object和Function都作为JS的自带函数,都继承自己,又相互继承对方,所以都既是函数也是对象。

console.log(Function instanceof Object)//ture
console.log(Object instanceof Function)//ture

表达式 var function f() {}; 与 var f = new Function();相等

普通对象和函数对象

JS万物皆为对象, 分为函数对象和普通对象,都由object衍生而来,即所有东西原型链终点指向null。函数对象可以创建普通对象,普通对象不能创建函数对象。凡是通过 new Function 创建的都是函数对象,其他都是普通对象(通常由Object 创建),可通过typeof判断。 function f(){} var o1 = new f(); var o2 = {}; typeof(f) // “function”; typeof(o1) // “object”; typeof(o2) // “object”

function f(){}  
var o1 = new f(); 
var o2 = {}; 
typeof(f); // “function” 
typeof(o1); // “object”
typeof(o2);// “object”

prototype 和__proto__

每个函数对象都有prototype属性,指向该函数的原型对象,是函数才有的属性,普通对象没有,prototype下面有一个constructor,指向这个函数

每个对象都有内部属性__proto__,指向它所对应的构造函数的原型对象,即“构造器的原型(即__proto__ === constructor.prototype)”,可通过Object.getPrototypeOf()标准方法访问该属性, 原型链基于__proto__
prototype是函数的属性,proto是对象的属性

Person.prototype.name = "aaa";
function Person(){
//var this = {__proto__: Person.prototype}
}
var person = new Person();
Person.prototype.name = "bbb";// 改属性值,所以person.name == "bbb"
//Person.prototype = {name: "ccc"}, peoson.name == "aaa",因为此时Person.prototype换对象,相当于
//Person.prototype = {name: "aaa"};
//__proto__ = Person.prototype;
//Person.prototype = {name: "ccc"};

原型继承 圣杯模式

  • 传统形式 原型链继承
    过多地继承了无用的属性
Grand.prototype.lastName = "haha";
function Grand(){}
var grand = new Grand();
		
Father.prototype = grand;
function Father(){}
var father = new Father();
		
Son.prototype = father;
function Son(){}
var son = new Son();
  • 借用构造函数
    不能继承借用构造函数的原型;
    每次构造函数都要多走一个函数。
function Person(name, age){
	this.name = name;
	this.age = age;
}
function Student(name, age, sex){
	Person.call(this, name, age);
	this.sex = sex;
}
var student = new Syudent();
  • 共享原型
    不能随便改动自己的原型
Father.prototype.name = "haha";
function Father(){}
Son.prototype = Father.prototype;
function Son(){}
  • 圣杯模式
function inherit(Target, Origin){
	function F() {};
	F.prototype = Origin.prototype;
	Target.prototype = new F();
	//Target修改自身属性时仅以f函数作为对象进行修改,不能= F.prototype
	Target.prototype.constructor = Target.prototype;
	//使Target.constructor=自己
	Target.prototype.uber = Origin.prototype;
	//记住自己的超类,真正继承自谁	
}
//立即执行函数和闭包,闭包:私有化属性 Yahoo
var inherit = (function(){
	function F(){}//闭包私有化属性 F
	return function(Target, Origin){
		F.prototype = Origin.prototype;
		Target.prototype = new F();
		Target.prototype.constructor = Target.prototype;
		Target.prototype.uber = Origin.prototype;
	}
}())
function F() {};
return (
)
}
Father.prototype.name = "haha";
function Father(){}
function Son(){}
inherit(Son, Father);
var father = new Father();
var son = new Son();
//constructor: son.__proto__ --> new F().__proto__ --> Father.prototype
//new F()为对象,没有prototype属性

你可能感兴趣的:(前段)