一寸光阴一寸金,寸金难买寸光阴!

    

JavaScript语言编程核心(一)--- 对象

JavaScript语言编程核心(一)--- 对象

对象

这是系列关于js语言核心思想的一些理解,包括对象、继承、原型链、构造函数、执行上下文堆栈、执行上下文、变量对象、活动对象、作用域链、闭包以及this。

本文参考自《JavaScript权威指南》、《JavaScript语言精粹》以及前端早读君的文章《javaScript核心》。

对象

在JavaScript中,对象是指可变的键控集合。属性名为字符串,值可以为任何类型的javascript值,每个属性都是一个名/值对。除了可以拥有属性外,对象还可以从一个称为原型的对象中继承属性。这就是JavaScript中的 “原型式继承”

1、属性特性:

在ES5中,属性还包括了一些标识可写、可枚举和可配置的特性。可以通过这些API给原型对象添加方法,并设置成不可枚举,让它们更像内置方法,也可以给对象定义不能修改或删除的属性,“锁定”该对象。
获取和定义可使用 getOwnPropertyDescriptor 和 defineProperty 方法:

    var o = {};
    Object.defineProperty(o,"x",{
        value:2,
        writable:true,   // 可写性;
        enumerable:false,   // 可枚举性;
        configurable:true     //  可配置性;
    });
    console.log(Object.getOwnPropertyDescriptor(o,"x" ));
    console.log(o.x);
  • 可写,表明是否可以设置改属性的值;
  • 可枚举,表明是否可以通过for/in循环返回;
  • 可配置,表明是否可以删除或修改该属性;

2、对象特性:

  • 对象的原型属性(prototype)通过隐含的__proto__属性指向另一个对象,可以继承原型对象的属性;
    Object.getPrototypeOf( )   // 可查询对象的原型;
    p.isPrototypeOf(o)   // 来检测p是否是o的原型;
  • 对象的类(class)是一个表示对象类型的字符串,用以表示对象的类型信息,一般用toString( )来获取:[Object class]。
    下面是封装好的 classof函数,用来检测对象类型;
    function classof(o){
        if(o === null){return "Null"};
        if(o === undefined){return "Undefined"};
        return Object.ptototype.toString.call(o).slice(8,-1);
    }
  • 对象的扩展标记(extensible flag)指明了是否可以向该对象添加新属性;ES5中,所有的内置对象和自定义对象都是显式可扩展的,宿主对象的可扩展性是依据引擎所定义的;
    Object.esExtensible( );   // 判断对象是否可扩展;
    Object.preventExtensions( ); // 将对象设置为不可拓展并且无法再转换回可拓展;但同样可以继承属性;
    Object.seal( );   // 封闭对象;将对象设置为不可拓展,而且将所有自有属性设置为不可配置;
    Object.isSealed( );  // 检测对象是否被封闭;
    Object.freeze( );   // 更严格的冻结对象,不可拓展,配置,且只读;
    Object.isFrozen( );   // 检测对象是否被冻结;

3、对象的分类:

  • 内置对象:JS内部定义的对象或类,如数组(Array)、函数(Function)、日期(Date)和正则表达式(RegExp)等;
  • 宿主对象:由js解释器所嵌入的宿主环境中定义的对象,如浏览器客户端;
  • 自定义对象:在JS代码中创建的对象;

4、对象属性的分类:

  • 自有属性:在对象内部定义的属性;
  • 继承属性:从原型对象中继承得到的属性;

5、 对象的创建:

  • 对象字面量法:
    一个对象字面量就是包围在一对花括号中的若干个名/值对组成的映射表,名与值之间用:分隔,名值对间用,分隔。该方法的__proto__指向Object.prototype.
    // 注意,最后一个名/值对后不再添加逗号;
    var student = {
        "name":"Tayde",
        "age":26
    }
  • new操作符+构造函数:
    通过new操作符后跟一个函数,初始化创建出一个新的对象,该方法的__proto__指向构造函数.prototype。
    var o = new Object();  // 与 var o = { }效果一样;
  • ES5中的Object.create( ):
    该方法可填两个参数,第一个填对象原型,第二选填自定义的属性;__proto__指向函数中填入的对象。
    var o1 = Object.create({x:1,y:2});  // 则o1对象已经继承了x,y属性;

6、对象属性的查询和设置:

  • .运算符,当属性名为一个简单的标识符时,一个静态值时使用;优先考虑,因为它有更好的可读性;
  • [ ]运算符,该方法更全面,当属性名为变量或动态值时使用;
    var name = student.name; 
    var age = student["age"];

Tips:
1、当属性不存在时,会返回 undefined,并不会报错;
2、但当查询属性的对象不存在时,则会报错;解决方法:

    var len = book && book.subtitle && book.subtitle.length;

3、可以用 ||运算符来填充默认值;

    var sex = student.sex || "unknown";

7、对象的引用:

对象通过引用来传递,他们永远不会被复制。
对象并没有被复制,而是仅仅将x,y指向同一个对象的引用而已。

    var x = {a:1};
    var y = x;
    y.a = 2;
    console.log(x.a);   // 2;

8、对象属性的删除:

    delete student.name;
    delete student["age"];

Tips:
delete操作符只能删除自身属性,无法删除原型上的继承属性;
delete操作符值是断开属性和宿主对象的联系,并不是删除属性,因此外部的引用仍会存在;

    var a = {x:{y:1}};
    var b = a.x;
    delete a.x;
    console.log(b);    // {y:1};
    console.log(a.x);  // undefined;

9、检测属性与对象的从属关系:

1、in运算符:

    var o ={x:1};
    console.log("y" in o);   // false;

2、hasOwnProperty( ):检测是否为自有属性,如果是继承属性,则返回false;

    var o = {x:1};
    console.log(o.hasOwnProperty("x" ));  // true;
    console.log(o.hasOwnProperty("toString" ));  // false;

3、propertyIsEnumerable( ): 属于hasOwnProperty的增强版,只有当属性为自有属性且可枚举性时,才返回true;

    var o = {x:1};
    console.log(o.propertyIsEnumerable("x" ));  // true;
    console.log(o.hasOwnProperty("y" ));  // false;
    console.log(o.hasOwnProperty("toString" ));  // false;

4、直接与undefined比较;

    var o = {x:1};
    o.x !== undefined;    // true;
    o.y !== undefined;    // false;

10、对象属性的getter和setter:

在ES5中,对象的属性值可以用一个或两个方法替代,他们就是getter和setter。由这两个方法定义的属性称作“存取器属性”。

    var serialnum = {
        "$n":0,
        get next(){
            return this.$n++;
        },
        set next(){
            if(n>=this.$n){this.$n = n;}else{throw "新值必须大于当前值。"}
        }
    }

11、序列化对象:

对象序列化是指将对象的状态转换成字符串,也可以将字符串转换为对象。使用ES5中的 JSON.stringify( ) 和 JSON.parse( )。

1、NaN、Infinity和-Infinity序列化后的结果是Null;
2、函数、RegExp、Error对象和undefined值不能序列化和还原;
3、JSON.stringify( ) 只能序列化对象可枚举的自有属性;

12、对象方法:

1、toString( ):无需参数,返回一个该对象的字符串。
2、toLocaleString( ):返回一个表示这个对象的本地化字符串。
3、toJSON( ):
4、valueOf( ):

所有原创文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站部分内容收集于互联网,如果有侵权内容、不妥之处,请联系我们删除。敬请谅解!

支持一下呗!Y(・∀・)Y
  • QQ
  • AliPay
  • WeChat

添加新评论

选择表情

  Timeline:今日文案

你看世界的眼光最要紧

updated on :

  关于博主

blog名-小优,平时喜欢跑步,喜欢听一些温柔,轻松的音乐,喜欢接触新事物,对自己的能力有一个很好的认知,人生在于折腾,一寸光阴一寸金,寸金难买寸光阴!我就是我,颜色不一样的烟火!

  近期评论

愚昧地去讨好别人,不如多给自己一点点关心! —— by 小优

每个人心里都有一段伤痕,时间才是最好的疗剂。

人总是珍惜未得到的,而遗忘了所拥有的。

退一步,并不象征我认输;放手,并不表示我放弃;微笑,并不意味我快乐!

人海中再回首,朋友真诚依旧,生命里重逢,心境平和温柔,往事如风,岁月如歌,漫漫人生路,苍桑几许,幸福几何!