二十一 Object对象
Object对象,是所有JavaScript对象的超类(基类)。Object.prototype(Obecjt的原型)定义了Js对象的基本方法和属性。
- new Object() :返回一个Object实例
- new Object(value) :根据value的值,返回不同的对象(Number、Boolean、String)
- 参数:value {number | bool | string} :一个数字、布尔值或者字符串
- 返回值:{Number、Boolean、String} 返回一个转换后的对象
var o = new Object(123);
console.log(o); // => Number对象
o = new Object(true);
console.log(o); // => Boolean对象
o = new Object('abc');
console.log(o); // => String对象
-
继承
- 创建一个临时对象,在临时对象的原型中存放获取到的对象;然后返回新对象
function obj(o){ function f(){}; f.prototype = o; return new f(); } //在这个函数中执行上面创建的obj函数 function transfrom(child,parent){ var new = obj(parent.prototype); prototype.constructor = child; child.prototype = new; } function sup(name){ this.name = name; this.color = ["red","blue","green"] } sup.prototype.sayName = function(){ console.log(this.name) } function sub(name,age){ sup.call(this,name) } transfrom(sub,sup); sub.prototype.sayAge = function(){ console.log(this.age) }
-
Object.is()比较两个值是否相等
console.log(Object.is('foo', 'foo'));//true console.log(Object.is({}, {}));//false console.log(Object.is(NaN, NaN));//true; console.log(Object.is([], []));//false console.log(Object.is('+0', '-0'));
-
Object.assign()对象的合并
var target = { a: 1 } var source1 = { b: 2 } var source2 = { c: 3 } Object.assign(target, source1, source2); console.log(target)//返回的是第一个写入的数组中
JSON.parse()把字符串转对象 只能解析标准的JSON类型。
JSON.stringify()把对象转字符串 按标准来解析(可以把不标准的JSON类型转为标准的)
-
实例属性
-
__proto__
:设置或返回对象的原型对象(IE中不支持此属性)- 赋值时,对象继承新原型的所有方法和属性,以及新原型的原型链中的所有方法和属性
- 属性名称以两个下划线开始和结束
- 对象的
__proto__
== 对象类的prototype
// 1.自定义对象多层继承 function People(name) { this.name = name; } function Student(age) { this.age = age; } Student.prototype = new People(); // 设置Student的原型为People对象 var s = new Student(22); console.log(s.__proto__); // => People 对象 console.log(Student.prototype); // => People 对象 console.log(s.__proto__ == Student.prototype); // => true // 2.对象直接量 var p = {}; // 等于new Object() console.log(p.__proto__ == Object.prototype); // => true
-
-
prototype
- 设置或返回对象类的原型对象
- prototype为对象类的属性。proto是对象的属性。
- Js内置对象(Array、Date等对象)都有一个只读的prototype属性。 可将属性和方法添加到原型中,但不能为内置对象分配其他原型。
- 自定义对象的prototype属性可进行读写操作。
var Student = function (name) { this.name = name; }; // 给Student的原型添加一个sayHello方法 Student.prototype.sayHello = function () { alert('Hello,' + this.name); } var st = new Student('张三'); // 初始化对象st console.log(st.name); // => 张三 st.sayHello(); // 弹出:Hello,张三
- 设置或返回对象类的原型对象
-
constructor
- 表示创建此对象的构造函数
- 设置或返回创建此对象的构造函数。
- 若一个对象有多层继承,将返回最先调用的构造函数。
- obj.constructor.prototype 可表示对象的原型。
// 1.内置对象 var str = 'abc'; console.log(str.constructor); // => function String 构造函数 var o = {}; console.log(o.constructor); // => function Object 构造函数 // 2.自定义对象多层继承 :constructor返回最先调用的构造函数 function People(name) { this.name = name; // s对象初始化时,先调用People构造函数,再调用Student构造函数 console.log('People调用'); } function Student(age) { this.age = age; console.log('Student调用'); } Student.prototype = new People(); // 设置Student的原型为People对象 var s = new Student(22); console.log(s.constructor); // => function People 构造函数
- 表示创建此对象的构造函数
-
proto、prototype、constructor 的关系
- 对象的proto 等于 类的prototype
- 对象的constructor 等于类,所以obj.constructor.prototype 可表示对象的原型。
var o = {}; console.log(o.__proto__ === Object.prototype); // true :对象的__proto__等于类的prototype console.log(o.constructor === Object); // true :对象的constructor 等于 类 console.log(o.constructor.prototype === Object.prototype); // true :o.constructor.prototype 可表示对象的原型。
-
实例方法
- hasOwnProperty(propertyName) :判断对象是否拥有一个指定名称的实例属性(非继承)
- 参数:propertyName {string} :属性名称。
- 返回值:{bool} 判断对象是否拥有一个指定名称的本地定义(非继承)的属性;此方法不会检查对象原型链中的属性。
- true :属性为对象的实例属性,非继承。
- false :属性不为对象的实例属性。
//示例 : // 1.Object对象 var o = new Object(); o.name = '自定义属性'; // 定义一个实例属性 console.log(o.hasOwnProperty('name')); // => true:name属性为实例o自己定义的,而非继承 console.log(o.hasOwnProperty('toString')); // => false:toString为继承属性 // 2.自定义对象 var Student = function (name) { this.name = name; }; // 给Student的原型添加一个sayHello方法 Student.prototype.sayHello = function () { alert('Hello,' + this.name); } // 给Student的原型添加一个age属性 Student.prototype.age = ''; var st = new Student('张三'); // 初始化对象st console.log(st.hasOwnProperty('name')); // => true :调用构造函数时,通过this.name附加到实例对象上 console.log(st.hasOwnProperty('sayHello')); // => false :sayHello方法为原型上的成员 console.log(st.hasOwnProperty('age')); // => false :age属性为原型上的成员
-
isPrototypeOf(obejct) 判断某个原型是否出现在对象的原型链中
- 语法:prototype.isPrototypeOf(object)
- 参数:obejct {object} :被检测的对象。
- 返回值:{bool} 返回某个原型是否出现在对象的原型链中
- true :是
- false :不是
// 1.Obejct对象 var o = new Object(); console.log(Object.prototype.isPrototypeOf(o)); // => true :o为Obejct一个对象 // 2.Array var array = [1, 2, 3]; console.log(Array.prototype.isPrototypeOf(array)); // => true :数组原型 console.log(Object.prototype.isPrototypeOf(array)); // => true :Object是所有对象的基原型 // 3.自定义对象 var People = function () { } var Student = function () { } // 设置Student类的原型为People Student.prototype = new People(); var st = new Student(); console.log(Student.prototype.isPrototypeOf(st)); // => true :st为Student一个对象 console.log(People.prototype.isPrototypeOf(st)); // => true :Student的原型为People console.log(Object.prototype.isPrototypeOf(st)); // =>true :Object是所有对象的基原型
-
propertyIsEnumerable(propertyName) :判断指定名称的属性是否为实例属性并且是可枚举的(可用for/in循环枚举)
- 参数:propertyName {string} :属性名称
- 返回值:{bool} 判断属性是否为实例属性并且是可枚举的(可用for/in循环枚举),不考虑原型链中的成员。
- true :是
- false :不是
// 1.Array对象 var array = [1, 2, 3]; array.name = 'Array'; console.log(array.propertyIsEnumerable('name')); // => true :name属性为实例属性 console.log(array.propertyIsEnumerable('join')); // => false :join方法继承自Array console.log(array.propertyIsEnumerable('length')); // => false :length属性继承自Array console.log(array.propertyIsEnumerable('toString')); // => false :toString方法继承自Object // 2.自定义对象 var Student = function (name) { this.name = name; } // 定义一个原型方法 Student.prototype.sayHello = function () { alert('Hello' + this.name); }; var a = new Student('tom'); console.log(a.propertyIsEnumerable('name')); // => true :name为自身定义的实例属性 console.log(a.propertyIsEnumerable('age')); // => false :age属性不存在,也返回false console.log(a.propertyIsEnumerable('sayHello')); // => false :sayHello属于原型方法
toLocaleString() :返回当前对象的一个本地化的字符串表示
toString() :返回当前对象的一个字符串表示形式
-
valueOf() :返回当前对象的原始值
- 参数:无
- 返回值:{object} 返回当前对象关联的原始值,若没有相关联的值,则返回对象本身
var a = [1, 2, 3]; console.log(a.valueOf()); // => [1, 2, 3] var b = true; console.log(b.valueOf()); // => true var c = {}; console.log(c.valueOf()); // => Object {} var s = 'abc'; console.log(s.valueOf()); // => abc // 自定义个对象,重写valueOf var customObject = {}; customObject.valueOf = function () { return '自定义对象'; } console.log(customObject.valueOf()); // => 自定义对象
-
静态方法
- Object.create(prototype, propertyDescriptor):创建并返回一个指定原型和指定属性的对象
- 参数:
- prototype {prototype} :返回对象的原型,可以为null。若为null,对象的原型为undefined。
- propertyDescriptor {propertyDescriptor} 可选:属性描述符。
//属性描述符:设置属性的一系列特性; 语法格式: propertyName: { value: '', // 设置此属性的值 writable: true, // 设置此属性是否可写入;默认为false:只读 enumerable: true, // 设置此属性是否可枚举(通过for/in预付);默认为false:不可枚举 configurable: true // 设置此属性是否可配置;如:是否可以修改属性的特性及删除属性。默认为false } //返回值:{object} 返回一个指定原型和指定属性的对象 示例 : // 建立个自定义对象,设置name和age属性 var obj = Object.create(null, { name: { value: 'tom', writable: true, enumerable: true, configurable: true }, age: { value: 22 } }); console.log(obj.name); // => tom console.log(obj.age); // => 22 obj.age = 28; console.log(obj.age); // => 22 :age属性的writable默认为false,此属性为只读 for (p in obj) { console.log(p); // => name :只输出name属性;age属性的enumerable默认为false,不能通过for/in 枚举 }
- Object.defineProperties(object, propertyDescriptor) :添加/修改对象一个或多个属性的特性
- 参数:
- object {object} :对象
- propertyDescriptor {propertyDescriptor} 属性描述符。
- 若对象包含此属性,则是修改此属性的特性;否则为为对象添加此属性。
var obj = {}; // 为对象添加name和age属性 Object.defineProperties(obj, { name: { value: 'tom', enumerable: true }, age: { value: 22, enumerable: true } }); for (p in obj) { console.log(p); // => name、age :输出name和age属性 }
- Object.defineProperty(obj, propertyName, propertyDescriptor) :添加/修改对象指定属性的特性
- 参数:
- object {object} :对象
- propertyName {string} :属性的名称
- propertyDescriptor {propertyDescriptor} 属性描述符。
- 说明 :若对象包含此属性,则是修改此属性的特性;否则为添加此属性。
//示例: var obj = {}; // 添加一个name属性 Object.defineProperty(obj, 'name', { value: 'tom', writable: true, enumerable: true, configurable:true } ); console.log(obj.name); // => tom :输出name属性的value的值
- Object.freeze(object) :冻结对象,使其不能添加属性以及无法对现有的实例属性进行特性更改、值修改、属性删除等操作
- 参数:
- object {object} :对象
- 说明 :此操作不可逆,冻结后无法进行解封。只影响实例属性,不影响原型属性。
//示例: var obj = { name: 'tom', age: 22 }; Object.freeze(obj); // 冻结对象 obj.email = '123@qq.com'; console.log(obj.email); // undefined :无法添加属性 obj.age = 25; console.log(obj.age); // 22 :无法设置属性的值
- Object.getOwnPropertyDescriptor(object, propertyName) :返回对象属性的描述符
- 参数:
- object {object} :对象
- propertyName {propertyName} 属性名称
- 返回值:
- {propertyDescriptor} 属性描述符对象
//示例 : var obj = { name: 'tom', age: 22 }; var propertyDes = Object.getOwnPropertyDescriptor(obj, 'name'); console.log(propertyDes); // => Object {value: "tom", writable: true, enumerable: true, configurable: true} :输出描述符对象
- Object.getOwnPropertyNames(object) :返回一个数组,包含对象的所有实例属性和方法,不包含原型继承的属性和方法
- 参数:
- object {object} :对象
- 返回值:
- {Array} 一个数组,包含对象的所有实例属性和方法,不包含原型继承的属性和方法
var obj = { name: 'tom', age: 22, sayHello: function () { alert('Hello' + this.name); } }; console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回对象的实例成员
- Object.getPrototypeOf(object) :返回对象的上一级原型
- 参数:
- object {object} :对象
- 返回值:
- {object} 返回原型对象
// 1.对象直接量 var obj = { name: 'tom', age: 22, sayHello: function () { alert('Hello' + this.name); } }; console.log(Object.getPrototypeOf(obj)); // => Object 对象:对象直接量的原型为Object // 2.自定义对象 var People = function (name) { this.name = name; }; var p = new People('tom'); var people = Object.getPrototypeOf(p); console.log(people); // => People 对象:new 创建的对象使用构造函数的prototype属性作为他们的原型 console.log(Object.getPrototypeOf(people)); // => Object 对象:原型People的原型为Object
- Object.isExtensible(object) :判断是否可向对象添加新的属性
- Object.isFrozen(object) :判断对象是否冻结;true:不能修改对象的现有属性特性和值并且不能添加新的属性
- Object.isSealed(object) :判断对象是否封闭;true:不能修改对象的现有属性特性并且不能添加新的属性
- Object.keys(object) :返回一个数组,包含对象的可枚举的实例属性名称
- 参数:
- object {object} :对象
- 返回值:
- {Array} 返回一个数组,包含对象可枚举的实例属性名称
- 此方法与getOwnPropertyNames()类似,但getOwnPropertyNames()包含了可枚举和不可枚举的成员
//示例 : var obj = { name: 'tom', age: 22, sayHello: function () { alert('Hello' + this.name); } }; //getOwnPropertyNames与keys方法返回的内容都相同 console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回对象的所有实例成员 console.log(Object.keys(obj)); // => ["name", "age", "sayHello"] :返回对象的所有可枚举成员 // 设置对象的name属性不可枚举 Object.defineProperty(obj, 'name', { enumerable: false } ); //keys方法,只包含可枚举成员 console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回对象的所有实例成员 console.log(Object.keys(obj)); // => ["age", "sayHello"] :返回对象的所有可枚举成员
- Object.preventExtensions(object) :设置对象不能添加新的属性
- 参数:
- object {object} :对象
- 返回值:
- {object} 返回此对象
//示例 : var obj = { name: 'tom', age: 22 }; Object.preventExtensions(obj); // 设置对象不能添加新的属性 obj.email = '123@qq.com'; console.log(obj.email); // => undefined :无法向对象添加新的属性
- Object.seal(object) :密封对象,使其无法修改现有属性的特性以及不能添加新的属性
- 参数:
- object {object} :对象
- 返回值:
- {object} 返回此对象
//示例 : var obj = { name: 'tom', age: 22 }; Object.seal(obj); // 密封对象 obj.email = '123@qq.com'; console.log(obj.email); // => undefined :无法向对象添加新的属性 // 报异常:无法修改对象属性的特性 Object.defineProperty(obj, 'name', { enumerable: false } );
-
属性描述符
- 属性描述符分为 "数据属性" 和 "访问器属性" ;
- 两者可相互转换,若转换后未设置enumerable和configurable特性(两类属性描述符都包含这2个特性),