zoukankan      html  css  js  c++  java
  • JavaScript 深入了解对象中的属性

      本篇主要介绍JS中对象的属性,包括:属性的分类、访问方式、检测属性、遍历属性以及属性特性等内容。

    目录

    1. 介绍:描述属性的命名方式、查找路径以及分类

    2. 属性的访问方式:介绍'.'访问方式、'[ ]'中括号访问方式

    3. 删除属性:通过delete关键字删除对象的某个属性

    4. 检测属性:介绍三种判断某个属性是否为对象的实例属性:in、obj.hasOwnProperty、obj.propertyIsEnumerable

    5. 遍历属性:介绍三种遍历对象的属性:for / in 语句块、Object.keys(obj) 、Object.getOwnPropertyNames(obj)

    6. 属性特性:在Escript5中,增加了属性特性这一内容,可设置属性是否可枚举、可修改等特性

    1. 介绍

    1.1 描述

      属性,特指对象的成员,不单单为'属性'(字段),也包含了方法。

    1.2 命名方式

    属性名称可以包含英文字符、数字(不能开头)、特殊符号(如:-、_、$等等)。

    但一般使用纯英文字符,在特殊情况下会添加-(横杠:-webkit-、-moz- )以及 _(下划线)。

    若属性名称包含了-(横杠),属性访问方式只能采用'[ ]'中括号访问:

    var o = {
        x: 1,
        y: 2,
        '-x': 3,
        '-showX': function () {
            alert(this.x);
        }
    }
    // o.-x; // 此访问方式会报异常
    console.log(o['-x']); // => 3 :读取带-(横杠)名称的属性,只能采用'[ ]'中括号访问方式
    o['-showX'](); // => 弹出1 :若方法名称带-(横杠),执行方式很别扭
    

    1.3 属性的查找路径

      假设读取某个对象的属性x,首先会在此对象的实例属性中查找。若没有找到,将会在此对象的原型对象中查找属性x。若原型对象也没有属性x,将继续查找这个原型对象的原型(假设原型对象含有原型),一直到找到属性x或者无原型为止。

    1.4 属性的分类

    对象中的属性,根据是否自身的可分为自有属性和继承属性。

    ① 自有属性:也可叫实例属性;指对象自身的属性。

    ② 继承属性:也可叫原型属性;指对象从原型中继承的属性。

    2. 属性的访问方式

    可分为 ' . '点访问方式和' [ ] '中括号方法方式 。

    说明:若读取一个不存在的属性,将返回undefined。若设置一个对象不存在的属性,将会向对象添加此属性。

    2.1 ' . '点访问方式 

    语法:obj.propertyName

    说明:属性名称必须为一个标示符(静态字符串),不能为变量。

    示例:

    var o = {};
    o.x = '1';
    

    2.2 ' [ ] '中括号访问方式

    语法:obj[propertyName]

    说明:属性名称可以为一个静态字符串,也可以为一个变量。若为变量,访问的属性为变量表示的值。

    特点:与'.'访问方式不同,'[ ]'中括号访问方式灵活性很大:可动态访问(变量指定属性名)、可访问包含某些特殊字符的属性(如:属性名称带'-')

    示例:

    var o = { x: 1, y: 2 };
    console.log(o['x']); // => 1 :访问x属性
    var a = 'y';
    console.log(o[a]); // => 2 :访问的是y属性(变量a的值)
    

    3. delete 删除属性

    语法:delete obj.propertyName 或者 delete obj[propertyName]

    说明:delete只能删除对象的自有属性,不能删除继承属性。

    示例:

    var o = {};
    o.x = '1';
    console.log(o.x); // => 1
    delete o.x;
    console.log(o.x); // => undefined :访问不存在的属性,返回undefined
    
    o.constructor.prototype.y = '2'; // 在原型对象上添加一个y属性
    console.log(o.y); // => 2
    delete o.y; // 删除继承属性y
    console.log(o.y); // => 2 :还是可以访问继承属性y
    

    4. 检测属性

      检测对象是否包含某个属性。

    4.1 in 运算符

    说明:判断对象是否包含某个属性,会从对象的实例属性、继承属性里进行检测。

    语法:propertyName in obj

    返回值:

    {bool} 判断对象的实例属性或继承是否包含此属性。

    true:对象的实例属性或继承属性包含此属性;

    false:对象的实例属性或继承属性不包含此属性。 

    示例:

    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('age' in s); // => true :age为实例属性
    console.log('name' in s); // => true :name为继承属性
    console.log('address' in s); // => false :address不存在此对象呢,返回false
    

    4.2 obj.hasOwnProperty(propertyName) 

    说明:判断对象是否拥有一个指定名称的实例属性,不会检查继承属性。

    参数:

    ①propertyName {string} :属性名称。

    语法:obj.hasOwnProperty(propertyName) 

    返回值: 

    {bool} 判断对象是否拥有一个指定名称的实例属性;此方法不会检查对象原型链中的属性。

    true :属性为对象的实例属性,非继承。

    false :属性不为对象的实例属性。

    示例:

    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属性为原型上的成员
    

    4.3 obj.propertyIsEnumerable(propertyName)

    说明:判断指定名称的属性是否为实例属性并且是可枚举的(可用for/in循环枚举)

    参数:

    ①propertyName {string} :属性名称。

    语法:obj.propertyIsEnumerable(propertyName)

    返回值:

    {bool} 判断属性是否为实例属性并且是可枚举的(可用for/in循环枚举),不考虑原型链中的成员。

    true :属性为对象的实例属性并且是可枚举的。

    false :属性不为对象的实例属性或不可枚举的。

    示例:

    var o = Object.create({}, {
        name: {
            value: 'tom',
            enumerable: true // 可枚举
        },
        age: {
            value: 22,
            enumerable: false // 不可枚举
        }
    });
    
    console.log(o.propertyIsEnumerable('name')); // => true :name为实例属性并且可枚举
    console.log(o.propertyIsEnumerable('age')); // => false :age为实例属性但不可枚举
    
    console.log(o.hasOwnProperty('age')); // => true :hasOwnProperty()方法只判断属性是否为实例属性
    

    4.4 总结

    检测方式 语法 检测属性的范围   返回值
    in 运算符 propertyName in obj 实例属性、继承属性 {bool} true:符合条件;fasle:不符合
    obj.hasOwnProperty(propertyName)  obj.hasOwnProperty(propertyName)  实例属性 {bool} true:符合条件;fasle:不符合
    obj.propertyIsEnumerable(propertyName) obj.propertyIsEnumerable(propertyName) 可枚举的实例属性 {bool} true:符合条件;fasle:不符合

    5. 遍历属性

      即遍历对象的实例属性、继承属性。

    5.1 for / in 语句块

    说明:遍历对象可枚举的实例属性和继承属性

    语法:

    for (p in obj) {
      // p表示遍历的属性名称
    }

    示例:

    var po = { px: 1, py: 2 };
    var o = { x: 1, y: 2 };
    o.__proto__ = po; // 设置o的原型为po
    for (property in o) {
        console.log(property); // => 输出属性的名称:x、y、px、py
        console.log(o[property]); // => 采用中括号访问方式,输出属性的值
    }
    

    5.2 Object.keys(obj) 

    说明:返回一个数组,包含对象可枚举的实例属性名称

    参数:

    ①obj {object} :实例对象

    返回值:

    {Array} 返回一个数组,包含对象可枚举的实例属性名称

    示例:

    var po = { px: 1, py: 2 };
    var o = { x: 1, y: 2 };
    o.__proto__ = po; // 设置o的原型为po
    var propertyArray = Object.keys(o); // => 返回一个包含了可枚举的实例属性名称的数组
    for (var i = 0, len = propertyArray.length; i < len; i++) {
        console.log(propertyArray[i]); // => 输出实例属性名称:x、y
    }
    

    5.3 Object.getOwnPropertyNames(obj) 

    说明:返回一个数组,包含对象的所有实例属性名称。包括可枚举和不可枚举的

    参数:

    ①obj {object} :实例对象

    返回值:

    {Array} 返回一个数组,包含对象所有实例属性名称

    与Object.keys()的差别:Object.keys()只返回可枚举的实例属性,Object.getOwnPropertyNames()返回所有实例属性

    示例:

    var po = { px: 1, py: 2 };
    var o = { x: 1, y: 2 };
    // 设置对象o的属性特性:属性x为可枚举,属性y为不可枚举
    Object.defineProperties(o, {
        x: {
            enumerable: true
        },
        y: {
            enumerable: false
        }
    });
    o.__proto__ = po; // 设置o的原型为po
    
    // 1.Object.keys():获取一个可枚举的实例属性名称的数组
    var propertyArray = Object.keys(o);
    for (var i = 0, len = propertyArray.length; i < len; i++) {
        console.log(propertyArray[i]); // => 输出实例属性名称:x 
    }
    
    // 2.Object.getOwnPropertyNames():获取一个包含的实例属性名称的数组,不管实例属性是否可枚举
    propertyArray = Object.getOwnPropertyNames(o);
    for (var i = 0, len = propertyArray.length; i < len; i++) {
        console.log(propertyArray[i]); // => 输出实例属性名称:x、y
    }
    

    5.4 总结

    检测方式 语法 遍历属性的范围   返回值
    for / in 语句块 for (p in obj) {
      // p表示遍历的属性名称
    }
    可枚举的实例属性和继承属性 {String} 属性的名称
    Object.keys(obj) Object.keys(obj) 可枚举的实例属性 {Array} 返回一个数组,包含对象可枚举的实例属性名称
    Object.getOwnPropertyNames(obj) Object.getOwnPropertyNames(obj) 包含对象的所有实例属性名称。包括可枚举和不可枚举的 {Array} 返回一个数组,包含对象所有实例属性名称

    6.属性描述符

    分为数据属性和访问器属性;

    两者可相互转换,若转换后未设置enumerable和configurable特性(两类属性描述符都包含这2个特性),将默认采用转换前的值。

    6.1 数据属性

    说明:包含属性的操作特性;如:设置值、是否可枚举等等

    特性名称 描述 默认值
    value 设置属性的值 undefined
    writable 是否可修改属性的值;true:可修改属性的值;false:不可修改属性的值 false  
    enumerable 是否可枚举属性;true:可枚举,可通过for/in语句枚举属性;false:不可枚举 false
    configurable 是否可修改属性的特性;true:可修改属性的特性(如把writable从false改为true);false:不可修改属性的特性 false

     

    默认值:

    1)在使用Object.defineProperty、Object.defineProperties 或 Object.create 函数的情况下添加数据属性,writable、enumerable和configurable默认值为false。

    2)使用对象直接量创建的属性,writable、enumerable和configurable特性默认为true。

    示例:

    // 1)对象直接量;属性特性默认为true
    var o1 = {
        name: 'tom'
    };
    console.log(Object.getOwnPropertyDescriptor(o1, 'name')); // => Object {value: "tom", writable: true, enumerable: true, configurable: true}
    
    // 2)通过Object.create创建,属性特性默认为false
    var o2 = Object.create(null, {
        name: {value:'tom'}
    });
    console.log(Object.getOwnPropertyDescriptor(o2, 'name')); // => Object {value: "tom", writable: false, enumerable: false, configurable: false}
    

    6.2 访问器属性

    说明:设置属性的访问方式;set、get特性等

    特性名称 描述 默认值
    get 属性的返回值函数 undefined
    set 属性的设置值函数;含有一个赋值参数 undefined
    enumerable 是否可枚举属性;true:可枚举,可通过for/in语句枚举属性;false:不可枚举 false
    configurable 是否可修改属性的特性;true:可修改属性的特性(如把writable从false改为true);false:不可修改属性的特性 false

    示例:

    var obj = {};
    
    // 添加一个属性,并设置为访问器属性
    Object.defineProperty(obj, "name", {
        get: function () {
            return this._name; // get和set里的变量不要使用属性,如:属性为name,get和set用的是_name
        },
        set: function (x) {
            if (isNaN(x)) {
                this._name = x;
            } else {
                this._name = 'name不能为纯数字';
            }
        },
        enumerable: true,
        configurable: true
    });
    
    console.log(Object.getOwnPropertyDescriptor(obj, 'name')); // => Object {get: function, set: function, enumerable: true, configurable: true} 
    obj.name = '12';
    console.log(obj.name); // => name不能为纯数字
    
  • 相关阅读:
    Visual Studio 2010的活动,有兴趣的朋友可以来参加
    .NET 业务框架开发实战之九 Mapping属性原理和验证规则的实现策略
    Javascript 返回上一页
    Entity Framework 4.0新增对TSQL的支持
    .Net 4.0中支持的更加完善了协变和逆变
    c#4.0——泛型委托的协变、逆变
    JQuery 常用方法基础教程
    AspNetPager分页示例
    微软一站式示例代码浏览器
    UI与实体的映射
  • 原文地址:https://www.cnblogs.com/polk6/p/4562281.html
Copyright © 2011-2022 走看看