虽千万人,吾往矣

JavaScript 面向对象(五)原型链

 

5. 原型链

prototype 原型
'每一个构造函数都有一个属性叫做prototype,指向一个对象,'
当这个构造函数被new 的时候,它的每一个实例 (即将生成的对象)的__proto__属性,也指向这个对象

function User() {
	console.log(this);
	this.name = 'whh';  //即将生成的对象
	this.age = 18;
}

var whh =new User();
console.log(whh); //whh这个对象

User {}
	age: 18
	name: "whh"
	__proto__:	Object
		constructor: ƒ User()
			arguments: null
			caller: null
			length: 0
			name: "User"
			prototype: {constructor: ƒ},
				constructor: ƒ User()
				__proto__: Object
			__proto__: ƒ ()
				apply: ƒ apply()
				arguments: (...)
				bind: ƒ bind()
				call: ƒ call()
				caller: (...)
				constructor: ƒ Function()
				length: 0
				name: ""
				toString: ƒ toString()
				Symbol(Symbol.hasInstance): ƒ [Symbol.hasInstance]()
				get arguments: ƒ ()
				set arguments: ƒ ()
				get caller: ƒ ()
				set caller: ƒ ()
				__proto__: Object
				[[FunctionLocation]]: VM1753:1
			[[Scopes]]: Scopes[1]
		__proto__:	Object
			constructor: ƒ Object()
			hasOwnProperty: ƒ hasOwnProperty()
			isPrototypeOf: ƒ isPrototypeOf()
			propertyIsEnumerable: ƒ propertyIsEnumerable()
			toLocaleString: ƒ toLocaleString()
			toString: ƒ toString()
			valueOf: ƒ valueOf()
			__defineGetter__: ƒ __defineGetter__()
			__defineSetter__: ƒ __defineSetter__()
			__lookupGetter__: ƒ __lookupGetter__()
			__lookupSetter__: ƒ __lookupSetter__()
			get __proto__: ƒ __proto__()
			set __proto__: ƒ __proto__()

每个'函数天生都有prototype属性,指向一个空对象, prototype属性的值是一个对象',也就是说,
我们不需要定义这个prototype属性,任何一个函数只要写出来,它就拥有了prototype属性,
这个属性对它自己而言没有任何意义!它的唯一意义是儿子们 (即将生成的对象)的指明灯!
'构造函数的 prototype属性 指向谁,它new出来的儿子的__proto__属性就指向谁''

function People(name,age,sex) {
	this.name =name;
	this.age =age;
	this.sex =sex;
}
var ming =new People('ming',12,'nan');

console.log(People.prototype===ming.__proto__);	//true

console.log(whh.__proto__); //whh这个对象
console.log(User.prototype);//或者也是一样的

'称 People.prototype是People构造函数的 “原型”,People.prototype是ming的 “原型对象”'

5.1

__proto__是神器,有原型链查找功能,当'ming身上没有某个属性'的时候,
'系统会沿着ming的属性__proto__去寻找它的原型对象身上有没有这个属性。''

5.2构造函数的prototype指向谁,new 出来的玩意儿的__proto__就指向谁!!!

这个__proto__有'原型链查找功能''

function People(name,age,sex) {
	this.name =name;
	this.age =age;
	this.sex =sex;
}
People.prototype ={
	"teacher":"kao",
	"sada":12,
}
var ming =new People('ming',12,'nan');
alert(ming.teacher); //kao
alert(ming['teacher']); //kao


People.prototype=Math; 						//Math所属对象None
var ming =new People('ming',12,'nan');
alert(ming.random());

ming身上虽然没有random属性,但是小明的__proto__身上有这个属性,
所以ming能够打点调用random属性。

5.3在原型上定义方法

刚才知道如果'把函数写在构造函数里面',就相当于'定义在了对象上',
'此时函数会产生多个不用的副本,影响程序效率,''
此时可以把函数'定义在构造函数的原型'上,
这样所有new出的东西, __proto__就会指向这个对象,从而能够使用这个方法。

function People(name,age,sex) {
	this.name =name;
	this.age =age;
	this.sex =sex;
}
People.prototype.funName=function () {				//important
	console.log(this);
	console.log("woshi:"+this.name+"!nianling:"+this.age);
};
var ming =new People('ming',12,'nan');
var hong =new People('hong',13,'nv');
console.log(ming.funName());
console.log(ming.funName==hong.funName);	//true
console.log(ming.funName);

			People {name: "ming", age: 12, sex: "nan"}
				age: 12
				name: "ming"
				sex: "nan"
				__proto__:
					funName: ƒ ()
					constructor: ƒ People(name,age,sex)
					__proto__: Object
			woshi:ming!nianling:12,
			VM2101:1 ƒ () {console.log(this);
				console.log("woshi:"+this.name+"!nianling:"+this.age);
			}

5.4构造函数和实例的关系

构造函数:抽象,定义的是一类对象应该具有什么属性,什么方法, 描述规则,描述蓝图。

实例:具体,根据规则、蓝图创建的一个个具体的实例,它能拥有属性,并且能调用方法。

构造函数中,我们用prototype来定义方法,
'定义的是构造函数的 实例 的方法',不是构造函数的方法。

	<input type="button" value="为所有🐕吃饭" id="btn">
	<script type="text/javascript">
		var dogArr=[];
		function Dog(name,w) {
			console.log(this);
			/* Dog {} 
				name: "bai",
				w: 100,
				__proto__: Object
			*/ 
			this.name =name;
			this.w =w;
			dogArr.push(this);
		}
		Dog.prototype.eat=function () {				//important
			console.log(this);
			// console.log("woshi:"+this.name+"!nianling:"+this.age);
			this.w +=10;
		};
		var bai =new Dog('bai',100);
		console.log(bai);
		/*
		Dog {name: "bai", w: 100}
			name: "bai"
			w: 100
			__proto__: Object
		*/
		var hei =new Dog('hei',90);
		document.getElementById('btn').onclick=function () {
			for(var i=0 ; i<dogArr.length ; i++){
				dogArr[i].eat();
				console.log(dogArr[i].name + ':' +dogArr[i].w);
			}
		}		//加引号
	</script>

 

posted @ 2022-11-23 23:51  遥望星空脚踏实地  阅读(21)  评论(0编辑  收藏  举报