您的位置:晶晶的博客>前端>JavaScript核心:Object属性和相关方法

JavaScript核心:Object属性和相关方法

Object构造函数创建一个对象,如果给定值是nullundefined将会创建并返回一个空对象,否则将返回一个与给定值对应类型的对象。

Object的属性

Object.length

值为1,没有太多的实用意义。

Object.prototype

Object.prototype属性表示对象Object的原型对象;可用于实现基于原型的继承与属性的共享。由于JavaScript没有子类对象,原型是一种常用的方法,用于为某些表现为对象的函数创建一个“基类”。

在JavaScript中,所有的对象都是基于Object;所有的对象都继承了Object.prototype的属性和方法,它们可以被覆盖(除了以null为原型的对象,如 Object.create(null))。对象的原型的改变会传播到所有对象上,除非这些属性和方法被其他对原型链更里层的改动所覆盖。

//例子1
Object.prototype.constructor === Object // true
Object.constructor === Function  // true
Function.prototype.constructor === Function  // true

//例子2
function objectPrototype(name)
{
    this.name = name;
}//定义一个构造函数
objectPrototype.prototype.see = true;//为构造函数的原型增加属性
var objectInstance = new objectPrototype('dog');//实例化一个构造函数,得到一个实例化对象
objectInstance.constructer === objectPrototype.prototype.constructer; // true

//例子3
var Person = function() {
    this.canTalk = true;
    this.greet = function() {
        if (this.canTalk) {
            console.log('Hi, I\'m ' + this.name);
        }
    };
    this.prototypeFunction = function () {
        console.log('prototype defined function run');  
    }
};//定义Person构造函数以及构造函数本身的一些属性和方法<原型>
var Employee = function(name, title) {
    this.name = name;
    this.title = title;
    this.greet = function() {
        if (this.canTalk) {
            console.log("Hi, I'm " + this.name + ", the " + this.title);
        }
    };
};//定义Employee 构造函数以及构造函数本身的一些属性和方法<另外一个原型>
console.log(Employee.prototype); // 输出Object原型本身
Employee.prototype = new Person();//将Employee的原型覆盖,赋值为Person的对象实例
console.log(Employee.prototype); // 输出Person原型本身
var inst = new Employee('1','2');
inst.prototypeFunction();// 输出 prototype defined function run

Object.prototype对象的属性

这里应该这样说更好理解:Object属性值prototype指向的对象的属性汇总。

Object.prototype.constructor

返回一个指向创建了该对象原型的函数引用。需要注意的是,该属性的值是那个函数本身,而不是一个包含函数名称的字符串。

Object.prototype.__proto__

这是个标准中已废弃的属性,但不少浏览器实现了该属性。有些地方称之为隐式原型,隐式原型指向创建这个对象的函数(也就是构造函数constructor)的prototype;代码中一般不要再使用该属性。

Object.prototype对象的方法

这里应该这样说更好理解:Object属性值prototype指向的对象的方法汇总。

Object.prototype.hasOwnProperty()

该方法会返回一个布尔值,所有继承至Object的对象都会继承到hasOwnProperty方法。这个方法可以用来检测一个对象是否含有特定的自身属性(非继承属性)。

语法:obj.hasOwnProperty(prop)

//例子3
var o = new Object();//实例化一个对象
o.prop = 'exists';//为该对象添加一个属性
console.log(o.hasOwnProperty('prop'));   // 返回 true
delete o.prop;
console.log(o.hasOwnProperty('prop'));   // 返回 false

//例子4
function proto()
{
    this.eye = 1;
}
proto.prototype.see = 'yes';
console.log(proto.hasOwnProperty('see')); // false
var ins = new proto();
ins.see = 'no';
console.log(ins.hasOwnProperty('see')); // true
console.log(ins.see); // 输出 no
delete ins.see;
console.log(ins.hasOwnProperty('see')); // false
console.log(ins.see); // 输出 yes

Object.prototype.isPrototypeOf()

测试一个对象是否存在于另一个对象的原型链上。

注: isPrototypeOfinstanceof operator 是不一样的。在表达式 object instanceof AFunction 中,检测的是 AFunction.prototype 是否在object 的原型链中,而不是检测 AFunction 自身。

当需要判断对象的后代是否在特定原型链上,这时候就需要用到instanceof

语法:prototypeObj.isPrototypeOf(object)

// 例子5
function Fee() {} // 构造函数1
function Fi() {} // 构造函数2
Fi.prototype = new Fee(); // 构造函数1成了构造函数2的对象原型--继承
function Fo() {} // 构造函数3
Fo.prototype = new Fi(); //构造函数2成了构造函数3的对象原型--继承
function Fum() {} // 构造函数4
Fum.prototype = new Fo();//构造函数3成了构造函数4的对象原型--继承
var fum = new Fum();// 实例化构造函数4

// 检测构造函数2的原型即Fi.prototype是否在fum对象实例<构造函数4>的原型链上
if (Fi.prototype.isPrototypeOf(fum)) {
    
}

Object.prototype.propertyIsEnumerable()

返回一个布尔值,表明指定的属性名是否是当前对象可枚举的自身属性。

语法:obj.propertyIsEnumerable(prop)

该方法可以判断出指定对象里的属性是否可枚举,也就是说该属性是否可以通过for...in循环等遍历到,不过有些属性虽然可以通过for...in循环遍历到,但因为它们不是自身属性,而是从原型链上继承的属性,所以该方法也会返回false。如果对象没有指定的属性,该方法返回 false。

// 例子6
var o = {};// Object空对象
var a = [];// Array数组对象
o.prop = 'is enumerable';
a[0] = 'is enumerable';

o.propertyIsEnumerable('prop');   //  返回 true
a.propertyIsEnumerable(0);        // 返回 true
a.propertyIsEnumerable('length');   // 对象内置属性length是否可枚举 返回 false

Object.prototype.toString() 和 Object.prototype.toLocaleString()

返回一个表示该对象的字符串。

语法:object.toString()

每个对象都有一个 toString() 方法,当对象被表示为文本值时或者当以期望字符串的方式引用对象时,该方法被自动调用。默认情况下,toString() 方法被每个继承自Object的对象继承。

后者toLocaleString()方法会内部调用toString()方法,没有差异。

Object.prototype.valueOf()

方法返回指定对象的原始值。

语法:object.valueOf()

valueOf()把对象转换成原始类型的值(数值、字符串和布尔值),很少需要显式的调用此函数;当遇到需要转换成一个原始值的情况时, JavaScript会自动调用此方法。默认情况下, valueOf() 会被每个对象Object继承。每一个内置对象都会覆盖这个方法为了返回一个合理的值,如果对象没有原始值,valueOf() 就会返回对象自身。

Object的方法

Object.assign(target, ...sources)

将所有可枚举的属性的值从一个或多个源对象复制到目标对象并返回目标对象。第一个参数为目标对象,第二个及以后为源对象。如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖。后来的源的属性将类似地覆盖早先的属性。

这个方法因为脑残IE未实现,短期内基本上不能用。

Object.create(proto, [ propertiesObject ])

用指定的原型对象和其属性创建了一个新的对象。可用于实现JavaScript对象的单继承、多继承

proto 一个对象,应该是新创建的对象的原型。

propertiesObject 可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(这些属性描述符的结构与Object.defineProperties()的第二个参数一样)。注意:该参数对象不能是undefined,另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。

如果 proto 参数不是 null 或一个对象值,则抛出一个 TypeError 异常。

此方法在IE8及其以下版本中未实现。

Object.defineProperty()

在obj对象上定义一个新属性prop,或者修改一个对象的现有属性prop, 并返回这个对象。

一般情况下,我们为对象添加属性是通过赋值来创建并可在属性枚举中被枚举的(for...inObject.keys 方法), 但这种方式添加的属性值可以被改变,也可以被删除。而使用 Object.defineProperty() 则允许改变这些额外细节的默认设置。

语法:Object.defineProperty(obj, prop, descriptor)

参数含义:

obj 要在其上定义属性的对象

prop 要定义或修改的属性的名称

descriptor 被定义或修改的属性描述符

-------------------------------------------------------------------------------------------------

何为属性描述符呢?属性描述符有两种主要形式:数据描述符和存取描述符。

数据描述符是一个描述数据可写、可配置、可枚举依据属性值的对象;数据描述符的格式如下:

{
    configurable: false,//属性是否可配置--配置一次后再次进行配置修改其特性
    enumerable: false,//属性是否可枚举
    writable: false,//属性是否可写--是否可重写
    value: null
}

存取描述符是由一对getter-setter函数来描述的属性,也就是说包含一对set/get函数属性的对象来定义,当prop属性被赋值时触发set函数,当调用prop属性时get函数被触发,有点儿Java语言里的getter/setter的意思,一种数据设置、读取的模式而已,无需过多深究,格式如下:

{
    set: undefined,
    get: undefined,
    configurable: false,//属性是否可配置--配置一次后再次进行配置修改其特性
    enumerable: false,//属性是否可枚举
}

-------------------------------------------------------------------------------------------------

需要留意的是:属性描述符的两种方式中仅能选用某一种方式来描述,也就是要么选择数据描述方式要么选择存取描述符方式。如果描述符的configurable特性为false(non-configurable),那么除了writable外(writable特性也只能修改为false),其他特性都不能被修改,并且数据和存取描述符也不能相互切换。

此方法在IE8及其以下版本中未实现,ES5新增特性,可以实现对象属性赋值、取值时触发setter、getter执行一些动作逻辑,可以考虑在新式浏览器中使用。

Object.defineProperties()

在一个对象上定义一个或多个新的属性或修改一个或多个已有属性,并返回该对象。defineProperty()方法仅新增或修改一个属性,defineProperties()方法可一次新增或修改多个属性。仅参数个数和格式上有略微区别。

语法:Object.defineProperties(obj, props)

obj 被添加属性或修改属性的对象实例

props 一个或多个键值对定义的要为对象添加或修改的属性的具体配置,键为添加的属性,值为属性描述符。

IE8及其以下未实现,ES5新增特性。

// 例子7
var a = {};
Object.defineProperties(a,{
    'b':{
        set : function () { return 1;},
        get : function () {return 2;}
    },
    'c':{
        value:'3',
        enumerable:false
    }
});

Object.getOwnPropertyDescriptor()

返回指定对象上一个指定的自有属性对应的属性描述符。

语法:Object.getOwnPropertyDescriptor(obj, prop)

obj 要在其上查询属性描述符的对象

prop 指定的一个属性名称

返回值:如果指定的属性存在于对象上,则返回其属性描述符(property descriptor),否则返回undefined。

此方法在IE7及其以下版本中未实现。

Object.getOwnPropertyNames()

返回一个指定对象的所有自身属性的属性名(包括不可枚举属性)组成的数组。

语法:Object.getOwnPropertyNames(obj)

obj 被检测的对象,其自身的可枚举和不可枚举属性的名称被返回

此方法在IE8及其以下版本中未实现,ES5新增特性

Object.getOwnPropertySymbols()

返回一个包含了指定对象自身的(非继承的)所有 symbol 属性键的数组。

语法:Object.getOwnPropertySymbols(obj)

该方法和 Object.getOwnPropertyNames() 类似,但后者返回的结果只会包含字符串类型的属性键,也就是传统的属性名。IE系列尚未实现。

Object.getPrototypeOf()

返回指定对象的原型(即内部[[Prototype]]属性的值)。

语法:Object.getPrototypeOf(object)

object 要返回其原型的对象。

返回值 给定对象的原型。如果没有继承属性,则返回null

此方法在IE8及其以下版本中未实现。

Object.is()

比较两个值是否是相同的值

语法:Object.is(value1, value2)

两等号判断会在比较时进行类型转换;三等号判等不会进行类型转换(如果类型不同会直接返回 false ); Object.is()在三等号判等的基础上特别处理了 NaN-0+0 ,保证-0+0 不再相同, Object.is(NaN, NaN) 也会返回 true(两等号和三等号的让NaN不等于其本身)。这三个运算符的原语中,没有一个会比较两个变量是否结构上概念类似。对于任意两个不同的非原始对象,即便他们有相同的结构, 以上三个运算符都会计算得到 false 。

脑残IE未实现该方法,需要兼容。

Object.keys()

返回一个由给定对象的自身可枚举属性组成的数组(原型链上的属性不会返回),数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致。

语法:Object.keys(obj)

此方法在IE8及其以下版本中未实现。

------------------

当然Object对象还有其他方法以及一些新特性方法,掌握上述属性、方法足以应付日常绝大多数的工作,非学院派就不逐一列出了。

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object

转载请注明本文标题和链接:《JavaScript核心:Object属性和相关方法

相关推荐

网友评论抢沙发

路人甲 表情
Ctrl+Enter快速提交