YDKJS04-原型

82 阅读2分钟

原型

5.1[[Prototype]]

	var myObj={
		a:2
	}
	myObj.a

[[prototype]]有什么用? 在试图引用对象的属性时会触发[[GET]]操作,比如myObj.a,对于默认的[[Get]]操作来说,第一步是检查对象本身是否有这个属性,如果有就引用他。

	var annotherObj={
		a:2
	}
	var myObj=Object.create(annotherObj);
	myObj.a;

5.1.1 Object.prototype

5.1.2属性设置和屏蔽

		var annotherObj={
			a:2
		}
		var myObj=Object.create(annotherObj);
		annotherObj.a;	//返回2
		myObj.a;		//返回2
		annotherObj.hasOwnProperty("a");	//true
		myObj.hasOwnProperty("a");	//false
		
		myObj.a++;	//隐式屏蔽
		annotherObj.a;		//返回2
		myObj.a;			//返回3
		
		myObj.hasOwnProperty("a");	//true

5.2 类

5.2.1 '类'函数

《你不知道的JS》这部分写得太罗嗦了,直接看MDN文档

类是创建对象的模板。它们用代码风住哪个数据以处理该数据。 类声明:

	class Rectangle{
		constructor(height,width){
			this.height=height;
			this.width=width;
		}
	}

提升:函数声明和类声明之间的一个重要区别在于,函数声明会提升,类声明不会。也就是变量声明提前

原型继承

对于使用过Java/C++的人来说JS有点困惑,因为它是动态语言,本身不带有class实现,在ES5/ES6中引用的class只是语法糖

1、继承属性

JavaScript对象是动态的属性“包”(指其自己的属性)。JavaScript对象有一个指向原型对象的链。 NOTES:

遵循ECMAScript标准,someObject.[[Prototype]]符号是用于指向someObject的原型。 从ES6开始[[Prototype]]可以通过Object.getPrototypeOf()和Object.setPrototypeOf()访问器来访问。

	let f=function(){
		this.a=1;
		this.b=2;
	}
	let o=new f();
	f.prototype.b=3;
	f.prototype.c=4;	
	/*
	不要再f函数的原型上直接定义f.prototype={b:3,c:4};这样会直接打破原型链
	*/
	console.log(o.a);	//返回1
	console.log(o.c);	//返回4

2、继承方法

JavaScript并没有其他基于类的语言所定义的方法。在JS中,任何函数都可以添加到任何对象上作为对象的属性。

	var o={
		a:2,
		m:function(){
			return this.a+1
		}
	}
	console.log(o.m());
	//当调用o.m时,'this'指向了o.
	
	var p=Object.create(o);
	//p
	
	p.a=4;
	console.log(p.m());
	//调用p.m 时,this指向了 p
	/

3、在JS中使用原型

	function doSomethding(){
	}
	console.log(doSomething.prototype);
	//和声明函数的方式无关
	//JavaScript中的函数永远有一个默认原型属性
	var doSomething=function(){}
	console.log(doSomething.prototype); 
	function doSomtheing(){}
	doSomething.prototype="bar";
	console.log(doSomething.prototype);

5.2.2 构造函数

1、构造函数还是调用

	function Foo(){
		
	}
	Foo.prototype.constructor===Foo;
	var a=new Foo();
	a.constructor==Foo

5.2.3 技术

JS模仿类的行为

	function Foo(name){
		this.name=name;
	}
	Foo.prototype.myName=function(){
		return this.name
	}
	var a=new Foo("a");
	var b=new Foo("b");
	a.myName();		//返回a
	b.myName();		//"b"

5.3原型继承

	function Foo(name){
		this.name=name;
	}
	Foo.prototype.myName=function(){
		return this.name
	}
	function Bar(name,label){
		Foo.call(this,name);
		this.label=label
	}
	Bar.prototype.myLabel=function(){
		retrun this.label
	}
	var a=new Bar("a","obj a");
	a.myName();
	a.myLabel();

5.4对象关联

现在我们知道了,[[Prototype]]机制就是存在于对象中的一个内部链接,它会引用其他对象。

5.4.1创建关联

	var foo={
		something:function(){
			console.log("Tell me somthing good...")
		}
	}
	var bar=Object.create(foo);
	bar.something();

**NOTES:**Object.create(null)会创建一个拥有空(或者说Null)[[Prototype]]链接的对象。由于这个对象没有原型链,所以instanceof操作符无法进行判断。因此总是会返回false,这些特殊的空[[Prototype]]对象通常被称为"字典"