对象的prototype与property

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40169665/article/details/78549450
构造函数法:
function Person(name,age,sex){
①this.name = name;
this.age = age;
this.sex = sex;
}
prototype就是一个不可枚举的共用属性,它也是一个对象
首先,构造函数也是一个函数,也可以通过最普通的函数调用来使用(即不用new去实例化对象),但这就失去了构造函数存在的意义了,所以一般来说我们自己写的构造函数都会用new去使用,具体下面会说到

在原型链上添加name属性:
②Person.prototype.name = name ;//对应上方我给出的构造函数,原型链上的name属性被实例的name属性隐藏,实例化后的对象调用name属性时取出的是①而不是② 一个对象寻找自身的某个属性时,会先在自己的实例上寻找,如果在实例上找不到才再去原型链上寻找。
为了方便,我们会将Person.prototype进行封装,就不用每一次在prototype上添加属性时都再写一遍了
Person.prototype = {
constructor : Person,
name : "GaryCheung"//与②等价
}


构造函数赋值要用new:
var person1 = new Person("GaryCheung",19,"male");
alert(person1.name) //弹出GaryCheung;
因为使用new后返回的是这个函数的指向(当前上下文,this)(如果不用new的话就是加在window对象上),然后赋给我们命名的person1上
不用new的例子:
Person("GaryCheung",19,"male");
alert(name) //此处alert的为全局环境下的name,因为我们将Person直接用,所以他内部的this就是window,所以我们是变相在window(全局对象)下加了属性,所以alert出来的也是"GaryCheung";

当然 我们也可以手动去改变构造函数内的上下文 如:
var person3={};
Person.call(person3,"GaryCheung",19,"male");//个人不推荐这种写法,即使这写法类似于我们用new的方法
alert(name); //报错,因为这里已经通过call将Person构造函数里的上下文(this)改为指向person3而不是指向默认的window了;
alert(person3.name);//弹出"GaryCheung";

再讲讲原型链的存在的必要性:
原型链上的属性与方法是被所有该构造函数下的实例化对象所共用的,每一个对象内部都有一个[[prototype]]属性,经常调试控制台的就会看到过__proto__(我用的chrome),这个[[prototype]]属性指向的都是同一个地
址,即他们都是相同的引用,牵一发而动全身,下面重新给出一些例子:

function Person(){}
Person.prototype.name = "GaryCheung";
Person.prototype.age = 19;
var person1 = new Person();
var person2 = new Person();
person1.__proto__.name = "Cheung";
console.log(person2.name);//"Cheung",因为person1与person2的prototype都是指向同一个地方
以及prototype的属性不是直接修改的,引用上面的构造函数做修改:
person1.name = "Cheung";
alert(person1.name) //"Cheung"
alert(person2.name) //"GaryCheung",因为person1.name = "Cheung";这句语句只是替person1这个实例对象在property上加了name属性,隐藏了他自身的prototype的name属性,但是其他的Person实例对象不会受影响
下面是我在控制台的输出:
在我理解中,构造函数的prototype就是一个父类,构造函数自身就是一个子类,这个构造函数是继承于prototype的,所以可以在自身里隐藏掉继承回来的属性或方法。

function Property(){};
Property.prototype.name = "GaryCheung";
Property.prototype.age = 19;
Property.prototype.sex = "male";
var p1 = new Property();
用java表示就是:
class Prototype{
String name = "GaryCheung";
int age = 19;
String sex = "male";
}
class Property extends Prototype{

}
Property p1 = new Property();
可以通过一些方法判断一个属性或方法是否为自身属性或方法:
alert(Object.getPrototypeOf(p1) == Property); //true,p1的原型是Property
alert(p1.hasOwnProperty("name"));//false,p1自身property没有name这个属性,它的prototype才有name这个属性




猜你喜欢

转载自blog.csdn.net/weixin_40169665/article/details/78549450
今日推荐