客户端去服务器端请求数据,因外因返回的数据(大多为json)可能不太一致,有些属性可能存在,也可能不存在,这种情况下如果我们直接调用,代码将抛出异常,因此,对于这些属性,需要预先做判断。
# 对象属性的访问流程
每当代码读取对象的某个属性时,都会执行一次搜索,找出有给定名字的属性。搜索首先从对象本身开始,如果在找到了目标属性,则返回该属性的值;如果没找到,将搜索指针指向原型对象, 如果在原型对象中找到目标属性,则返回该属性的值;
虽然可以通过对象实例找到原型对象中的属性的值,但却不能通过对象实例重写原型对象的值。
假设对象实例具有一个与原型对象相同属性名的属性,则在访问该属性时,会返回对象实例的属性值。即原型对象的属性被屏蔽。因此,添加同名属性只会阻止访问原型对象的属性值,但不会修改那个属性。即使将对象实例中的属性值改为null
,也不会影响原型对象的属性。
因为有了如此差别,所以需要对对象属性的存在方式加以区分,因此有了in
和hasOwnProperty()
- in: 只要能通过对象访问到(对象实例或原型对象中存在)就返回 true ;
-
hasOwnProperty():只有当对象实例存在时才返回true,不检索原型对象;
# in 与 hasOwnProperty() 的区别
function Person() { // 构造函数
}
Person.prototype.name = "zao";
Person.prototype.age = "24";
Person.prototype.job = "Software Engineer";
Person.sayName = function() {
alert(this.name);
};
var person1 = new Person();
console.log(person1.hasOwnProperty('name')); // false
console.log("name" in person1); // true
person1.name = "an"
console.log(person1.name); // an
console.log(person1.hasOwnProperty('name')); // true
console.log("name" in person1); // true
delete person1.name;
console.log(person1.name); // "zao"
console.log(person.hasOwnProperty('name')); // false
console.log("name" in person1); // true
从上述实例证明,in
能访问到对象实例的属性和原型对象的属性,而hasOwnProperty()
只能访问对象实例本身。
另外,即使我们设置了对象实例的name
属性值为null
,调用console.log('name')
时,输出结果也为null
,因此如果想达到重新访问原型对象的属性值的时候,就需要调用如上中的delete
操作符,他可以完全删除实例属性,从而让我们达到重新访问原型对象的目的。
# 对象的 prototype 属性
几乎任何一个对象,都具有prototypeshuxign,他是一个隐藏属性,该属性指向的是对象的原型。对象的 prototype 属性使您有能力向对象添加属性和方法。
object.prototype.name=value
一个对象的prototype属性是由构造该对象的方法决定的,大致有三种:
- 字面量构造法
var person1 = {
name: 'zao',
job: 'Software Engineer'
}
该形式称作 对象字面量,他的原型链属性指向的是Object.prototype,该例即 person1.prototype
- 构造函数法
function Person() {
}
var person1 = new Person();
通过 new 调用的就是构造函数,由构造函数构造的对象,原型链指向构造函数的prototype属性指向的对象,因此本利中,person1的原型链属性指向的就是Person。prototype。
另外,每一个函数都有一个constructor
属性,这一属性默认指向函数本身。
在ES5规范中,每一个对象都有一个_proto_
属性,属性指向其父类的 prototype
; 即.__proto__ === .constructor.prototype
- Object.create法
var person1 = {
name: 'zao',
age: '24'
}
var person2 = Object.create(person1)
该例中,person2 的 prototype 指向的是对象 person1
后语
本文通过对 in 和 hasOwnProperty() 引伸出了比较难以理解的对象的原型属性,如果对这块还有困惑,可以自己做一下拓展,也欢迎交流一起进步。