5.JavaScript原型链和继承详解

Posted 且听风呤dzq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5.JavaScript原型链和继承详解相关的知识,希望对你有一定的参考价值。

javascript原型链和继承详解

上一篇 JavaScript作用域和闭包详细总结

下一篇 JavaScript浅层克隆和深层克隆


一、原型

1.定义:原型是 function 对象的一个属性,它定义了构造函数制造出的对象的公共祖
先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
2.利用原型特点和概念,可以提取共有属性。
3.对象属性的增删和原型上属性增删改查。
4.对象如何查看原型 ==> 隐式属性 __ proto __
5.对象如何查看对象的构造函数 ==> constructor。

自己身上有属性,原型上也有属性,取近的,用自己的

二、原型链

1、构成原型链

Grand.prototype.lastName = "dzq";
function Grand(){};
var grand = new Grand();//grand对象继承了祖先的的lastName属性
console.log(grand.lastName);

Father.prototype = grand;//将对象grand赋给Father的原型
function Father(){
    this.name = "lyh";
};
var father = new Father();//father就可以拿到lastName属性和它自己的name属性
console.log(father.lastName,father.name);

Son.prototype = father;//同理将对象father赋给Son的原型
function Son(){
     this.hehe = "txc";
};
var son = new Son();//son就能拿到lastName、name属性,和自己的hehe属性
console.log(son.lastName,son.name,son.hehe)

2、原型链上属性的增删改查
原型链上的增删改查和原型基本上是一致的。只有本人有的权限,子孙是没有的。

3、谁调用的方法内部 this 就是谁

4、绝大多数对象的最终都会继承自Object.prototype

5、Object.create(原型);
Object.create 也能创建对象。var obj = Object.create(这里必须要有原型)

6、原型方法上的重写
原型上有这个方法,我自己又写了一个和原型上同一名字,但不同功能的方法,叫
做重写(同一名字的函数,不同重写方式)
通过返回值,形参列表不同传参
同样的名实现不同功能的,就是重写

原型链图解

了解this与call/apply方法

this
1.函数预编译过程 this —>指向 window
2.全局作用域里 this —> 指向 window
3.obj.func(); func()里面的 this 指向 obj(谁调用这个函数this就指向谁)
4.call/apply 可以改变函数运行时 this 指向,它们两的区别,是后面传的参数形式不同。

call
直接执行 Person.call ( )和 Person ( )没有区别
Person.call( );括号里面可以传东西
如果 Person.call( obj );里面的 call 让 person 所有的 this 都变成 obj
不 new 的话,this 默认指向 window。call 的使用必须要 new
call 的第一位参数用于改变 this 指向,第二位实参(对应第一个形参)及以后的参数都当做正常的实参,传到形参里面去

function Person(name,age,sex){
	this.name=name;
	this,age=age;
	this.sex=sex;
}
function Student(name,age,sex,tel,grade){
	this.name=name;
	this.age=age;
	this.sex=sex;
	this.tel=tel;
	this.grade=grade;
}
var student =new Student("sunny","123","male",123,2000)
/*call 改变 this 指向,借用别人的函数,实现自己的功能。
只能在你的需求完全涵盖别人的时候才能使用
如果不想要 age 这个,就不能使用这种方法*/
function Person(name,age,sex){
	this.name=name;
	this,age=age;
	this.sex=sex;
}
function Student(name,age,sex,tel,grade){
	Person.call(this,name,age,sex)
	this.tel=tel;
	this.grade=grade;
}
/*Person.call(this, name, age, sex);里面的 this 现在是 new 了以后的 var this={}
利用 Person 方法,实现了 Student 自己的封装*/

apply
apply 也是改变 this 指向的,只是传参列表不同,第一位也是改变 this 指向的人,第
二位,apply 只能传一个实参,而且必须传数组 argunments
call 需要把实参按照形参的个数传进去

三、继承

继承发展史
1.传统形式 ==> 原型链
问题:过多的继承了没用的属性

2.借用构造函数 ==>利用 call、apply 所以不算标准的继承模式
1)不能继承借用构造函数的原型
2)每次构造函数都要多走一个函数 ==>浪费效率

3.共享原型(较好的继承方法)
不能随便改动自己的原型

Father.prototype.lastName = 'dzq';
function Father(){};
function Son(){};
Son.prototype = Father.prototype;//原型对象指向一个房间
var son = new Son();

圣杯模式
圣杯模式是在方法三的共有原型,但是在共有原型的基础上有改变。
共享原型是:son.prototype=father.prototype
圣杯模式是:另外加个构造函数 function F(){}当做中间层,然后让 F 和 father 共
有一个原型 F.prototype=father.prototype,然后 son.prototype = new F();使用原
型链形成了继承关系,现在改 son.prototype 就不会影响 father.prototype

var inherit = (function (){
	var F = function(){};//定义一个中间构造函数,私有化变量
	return function (target,origin){//target接受继承者,origin继承的目标
		F.prototype = origin.prototype;//将继承的目标原型对象赋给F.prototype
		target.prototype = new F();
		//new一个实例对象赋给接受继承的target
		//new后,Target.prototype指向的一个全新的地方
		//改变Target的原型链就不会影响到Origin
		target.prototype.constuctor = target;//将constructor指向自己
		target.prototype.uber = origin.prototype;//保存自己真正继承的目标,以便后期访问
	}
}());

以上是关于5.JavaScript原型链和继承详解的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript高级原型和继承相关:原型对象函数原型原型链和继承继承的优化对象判断相关方法

JavaScript高级原型和继承相关:原型对象函数原型原型链和继承继承的优化对象判断相关方法

原型链和继承

对Javascript的原型,原型链和继承的个人理解

js原型链和继承的理解

关于原型原型链和原型继承的理解