javascript基础-原型对象
1 原型对象

我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象,这个对象就是我们所谓的原型对象。

如图,每个我们创建的函数对象都会指向一个自己的原型对象。

- 如果函数作为普通函数调用prototype时没有任何作用(函数名称()调用的方式)
- 当函数以构造函数的形式调用时,他所创建的对象中会有一个隐含的属性指向该构造函数的prototype(原型对象),我们可以通过__proto__来访问该属性。

指向的是同一个原型对象,也就是上面的0x123

我们可以看到,p对象和p2对象指向的是同一个原型对象的地址。

不管有几个对象,都是一样的。也就是说,原型对象是一个类创建的所有对象的公共区域,该类的所有对象都可以访问到这个原型对象。所以一般我们将某个类的所有对象公有的内容设置到原型对象里。

可以看出,确实是公共的区域。

通过类设置原型对象,虽然p2对象中并没有name属性,但是公共区域有,在自身区域中找不到后,会去公共区域找。

如果我们在p2对象中设置了name属性,那么输出时自身有,就直接用自身的name了。
如图:

在原型对象中添加函数类型属性:

和普通类型属性一样,也是可以的。

使用原型对象,修改44次文档代码:

前一章节我们为了优化内存,将对象中重复的函数类型属性hanshu提取到了全局中,但是会存在一个隐患,那就是一旦协同开发中,其他程序员也使用了hs这名称定义函数的时候,会覆盖我们创建的hs函数,所以我们通过原型对象就可以解决这个问题:

首先实例化Persion让prototype生成并指向,然后向原型对象(prototype)中设置公共属性,这样Persion类的任何一个实例化的对象,都可以访问到公共区域的函数了,而且还避免了将公共函数放到全局的名称污染的问题。
通过类名定义也可以:

该法不必在定义原型对象属性前进行实例化操作,因为我们是通过类名直接定义的。
-------------------------------------------------------------------------------------------------------------------------
1 关键字in:判断某对象中是否存在相同名称的属性(原型对象中的属性也算)

2 hasOwnProperty()方法,查询自己对象中是否有某个属性


我们发现p对象中并没有hasOwnProperty()方法,那么p的原型中有没有呢?

我们发现p的原型对象自身中也是没有hasOwnProperty()方法的,那么该方法到底在哪?
如图:

其实原型对象中也存在原型对象的,就像普通对象中存在原型对象是一样的。

我们可以看到,果然
当然也可以用in关键字查询,更简单:

因为关键字in会查询所有的嵌套的对象包括嵌套的原型对象。
注意:原型对象的原型对象,只有这两层,并不是无限嵌套的:

注意:如果在对象中查询是否存在某个属性是,如果第二层原型对象中都不存在的时候,会一直向上查询到Object对象,如果Object对象中还没有,那么返回undefined,注:Object对象是没有原型对象的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function Person(){
}
var p=new Person();
var p2=new Person();
/* console.log(Person.prototype);//原型对象
console.log(p.__proto__);//结果与上面一致 */
/* // 通过对象p向原型对象中添加属性
p.__proto__.name="p";
// 通过对象p2从原型对象中读取属性
console.log(p2.__proto__);
// 结果 p和p2的protp原型对象中属性是公共的区域 */
/* Person.prototype.name="p";
console.log(p2.name);//如果p2自身没有name属性,则在公共区域找name属性的值
// 通过类设置原型对象,虽然p2对象中并没有name属性,
// 但是公共区域有,在自身区域中找不到后,会去公共区域找。
p2.name="list";
console.log(p2.name);
// 如果我们在p2对象中设置了name属性,那么输出时自身有,就直接用自身的name了。 */
// 在原型对象中添加函数类型属性:
// 公共区域的函数
Person.prototype.fun=function(){
alert("p");
}
console.log(p2.fun());
console.log(p.fun());
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function Person(name,gender,age){
this.name =name;
this.gender =gender;
this.age =age;
// this.hanshu=hs;
}
function hs(){
alert(this.name);
}
var person1 = new Person("李红","女",20);
// 通过原型对象定义公共的方法
person1.__proto__.hanshu=function(){
alert(this.name)
}
console.log(person1.hanshu());
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function Person(){
}
var person1 = new Person();
// 向构造函数的原型对象中添加name属性
Person.prototype.name="lihong";
console.log(person1.name);
// 通过关键字in检查name属性是否存在p对象中存在
console.log("name" in person1);//true
// hasOwnProperty()方法,查询自己对象中是否有某个属性
console.log(person1.hasOwnProperty("name"));//false
console.log(person1.__proto__.hasOwnProperty("hasOwnProperty"));//false
// p的原型对象自身中也是没有hasOwnProperty()方法的
console.log(person1.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//true
// 在p的原型对象的原型对象中存在该方法。
// 注意:原型对象的原型对象,只有这两层,并不是无限嵌套的:
// 可以用in关键字查询,更简单:
console.log("hasOwnProperty" in person1);//true
// 因为关键字in会查询所有的嵌套的对象包括嵌套的原型对象。
// 注意:如果在对象中查询是否存在某个属性是,如果第二层原型对象中都不存在的时候,会一直向上查询到Object对象,如果Object对象中还没有,那么返回undefined,注:Object对象是没有原型对象的。
</script>
</head>
<body>
</body>
</html>

浙公网安备 33010602011771号