JavaScript高级程序设计第八章阅读第二部分

229 阅读3分钟

《JS高程第八章 第二部分》

继承

继承是面向对象oop编程中讨论最多的。许多oop语言都支持两种继承方式,接口继承和实现继承。

8.3.1原型链**(重点)**

JS高程的解释 每一个构造函数(star构造函数)都有一个原型对象(star原型对象),原型有一个函数(constructor)指回构造函数,而实例有一个内部指针指向原型(实例.proto)。如果原型是另一个类型的实例,那就意味着这个原型有一个内部指针(原型.proto)指向另一个原型,相应的另一个原型也有一个指针(原型.constructor)指向另一个构造函数。这样就在实例和原型之间构造了一条原型链

个人更推荐MDN文档的解释

在谈到继承的时候,JavaScript只有一种结构,那就是对象。每一个对象的实例都有一个私有属性(proto)指向它的构造函数的原型(prototype).该原型对象也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为null。根据定义,null没有原型,并作为原型链的中最后一个环节。换言之_proto_指到null就没了(这不就是链表吗?_proto_作为指向下一个的指针,然后每个节点有一个constructor函数指向构造函数,构造函数通过prototype指回节点)

下面代码用火狐打开

	let Star=function(Name,Age){
		this.age=Age;
		this.name=Name;
	}
	let jackMa=new Star("马云",58);
	console.log(jackMa);	//返回Object{name:"马云",age:58};
	console.log(jackMa.constructor);//这里返回构造函数 function Star(Name,Age){...}	继承了Star
	console.log(jackMa._proto_);	//这里返回对象{}里面有constructor和prototype
	console.log(jackMa.prototype);	//返回undefined
	console.log(jackMa.__proto__.constructor);	//返回构造函数function Star(Name,Age)
	console.log(jackMa.__proto__.prototype);	//返回undefined
	console.log(jackMa.__proto__.__proto__)		//返回对象Object,所有的对象都继承于Object
	console.log(jackMa.__proto__.__proto__.prototype);//返回undefined
	console.log(jackMa.__proto__.__proto__.constructor);	//返回 构造函数 function Object()
	console.log(jackMa.__proto__.__proto__.__proto__);	//返回 null

上面实例对象constructor指向的构造函数都继承于Star的构造函数,Star的构造函数继承于function Object()

2、原型与继承

原型与实例的关系可以通过两种方式来确定。第一种方式是使用instanceof操作符,如果一个实例的原型链中出现过相应的构造函数,则instancof返回true,否则返回false

MDN 1、继承属性

	let f=function(){
		this.a=1;
		this.b=2;
	}
	let o=new f();
	f.prototype.b=3;
	f.prototype.c=4;
	/*不要直接上面这样定义属性,会打破原型链*/
	
	console.log(f);		//返回 {b:3,c:4}
	console.log(o);		//返回 {a:1,b:2}
	console.log(o._proto_);	//返回 {b:3,c:4}
	console.log(o._proto_._proto_);//返回 Object
	console.log(o._proto_.proto_._proto_);	//返回null
	
	console.log(f.b);	//返回undefined
	console.log(f.c);	//返回4

MDN 2、继承方法

在JavaScript中,并没有其他语言那样的方法,任何函数都可以添加到对象上作为对象的属性。函数的继承与其他属性的继承没有差别,包括“属性遮蔽”相当于方法重写

	let o={
		a:2,
		m(){
			return this.a+1;
		}
	};
	console.log(o.m());	//返回3
	let p=Object.create(o);	//ES6之前的写法
	let p1=new o();			//ES6的写法
	p.a=4;
	console.log(p.m());	//返回5

MDN 3、在Javascript中使用原型

	function doSth(){}
	console.log(doSth.prototype);	//这里返回对象{constructor:f},constructor构造函数指向的是f doSth()
	//和声明函数的方式无关
	//JavaScript中的函数永远有一个默认原型属性
	var doSth=function(){};	
	console.log(doSth);		//这里返回对象{constructor:f},constuctor指向的是f()

	//

MDN 4、给原型对象添加属性

	function doSomthing(){}
	doSomthing.prototype.foo="bar";
	doSomthing.prototype.tel=110;
	console.log(doSomthing.prototype);	//这里返回对象doSth里面有两个属性	1、foo和2、tel

MDN 5、通过new来创建实例

	function doSth(){
		
	}
	doSth.prototype.thing="加班";
	let doSthInstacne=new doSth();
	doSthInstance.prototype.name="JackMa";
	console.log(doSthInstance);//这里返回对象
	/*
		doSth{
			name:"JackMa",
			_proto_:{
				thing:"加班"
				constructor:f doSth(){}
				_proto_:Object
			}
		}
	
	
	
	*/