• JavaScript中各存在性函数


    JavaScript中有很多表示存在性和从属关系的函数,本文介绍如下几个:

    1)有关实例与构造函数原型之间的关系:isPrototypeOf(),Object.getPrototypeOf();

    2)有关属性是否为实例属性:hasOwnProperty(),in操作符;

    3)遍历属性:for-in ,Object.keys(),Object.getOwnPropertyNames()。

    有关实例与原型之间的关系

    isPrototypeOf方法

    【定义】

    通过此方法可以确定对象之间是否存在__proto__关系(若不理解此关系,可参加文章原型链继承中的prototype、__proto__和constructor的关系)。

    【语法】

    obj1.isPrototypeOf(obj2);

    如果obj2的__proto__指针指向obj1,则返回true;否则返回false。

    【举例】

    function Person(){};
    var person1 = new Person();
    console.log(Person.prototype.isPrototypeOf(person1));//true

    因为person1的__proto__指向构造函数Person的原型,因此返回true。

    Object.getPrototypeOf方法

    【定义】

    此方法返回对象的__proto__值。

    语法:

    Object.getPrototypeOf(obj)

    举例

    function Person(){};
    var person1 = new Person();
    console.log(Object.getPrototypeOf(person1) == Person.prototype);//true

    Object.getPrototypeOf(person1)返回的是person1的__proto__值,即Person.prototype,因此上述代码返回true。

    有关属性是否为实例属性

    hasOwnProperty方法

    【定义】

    此方法可以检测一个属性是否存在与实例中。(关键词:属性存在实例中)

    【语法】

    obj.hasOwnProperty(attr)

    举例

    function Person(){};
    Person.prototype.name = "Bob";
    var person1 = new Person();
    person1.age = 20;
    console.log(person1.hasOwnProperty("name"));//false
    console.log(person1.hasOwnProperty("age"));//true

    name属性在Person的原型对象上,age属性在person1实例上,因此检测结果如上。

    in操作符

    【定义】

    确定对象是否存在某属性,无论其存在实例上还是原型中。(关键词:属性存在实例中或原型中)

    【语法】

    attr in obj

    【举例】

    function Person(){};
    Person.prototype.name = "Bob";
    var person1 = new Person();
    person1.age = 20;
    console.log("name" in person1);//true
    console.log("age" in person1);//true
    console.log("name" in Person.prototype);//true
    console.log("age" in Person.prototype);//false
    console.log( Person.prototype.hasOwnProperty("name"));//true

    name属性是person1的原型属性,name属性是person1的实例属性,因此在person1上应用in操作符,均返回true;但在Person.prototype上应用in操作符,只有name属性返回true,因为对于Person.prototype,此时name是它的实例属性(代码最后一行判断实例属性返回true),而age不是其属性。

    拓展:自定义hasPrototypeProperty方法

    JavaScript中没有内置可以判断属性是否只在原型上的方法,但我们可以通过hasOwnProperty方法和in操作符自定义此方法。

    function hasPrototypeProperty(obj,attr){
        return !obj.hasOwnProperty(attr) && (attr in obj)
    }

    通过确保属性attr在对象上(in操作符)且不为实例属性(hasOwnProperty方法 ),即可自定义判断原型属性的方法,如上。下面我们验证一下:

    function Person(){};
    Person.prototype.name = "Bob";
    var person1 = new Person();
    person1.age = 20;
    
    function hasPrototypeProperty(obj,attr){
        return !obj.hasOwnProperty(attr) && (attr in obj)
    }
    console.log(hasPrototypeProperty(person1,"name"));//true
    console.log(hasPrototypeProperty(person1,"age"));//false

    显示,结果正确。

    遍历属性

    for-in

    【定义】

    遍历所有存在与对象中的可枚举属性,包括实例上的和原型上的。(关键词:可枚举、实例属性和原型属性)

    【举例】

    function Person(){};
    Person.prototype.name = "Bob";
    var person1 = new Person();
    person1.age = 20;
    for(var key in person1){
        console.log(key + ":" + person1[key]);//返回两个结果,分别为age:20和name:Bob
    }
    //定义age属性不可枚举
     Object.defineProperty(person1,"age",{
        enumerable:false
     });
    for(var key in person1){
        console.log(key + ":" + person1[key]);//返回一个结果,为name:Bob
    }

    enumerable属性默认值为true,所以第一个for-in中返回了包括实例上和原型上的属性;当设置了age属性不可枚举时,age属性将无法再被for-in获取到,所以只返回了name属性。

    注意一点,当实例中的属性屏蔽了原型中不可枚举的属性时,该实例属性仍可被for-in返回,因为此时该实例属性仍可被枚举。

    Object.keys()方法

    【定义】

    返回对象包含的所有可枚举实例属性的字符串数组。(关键词可枚举、实例属性)

    【语法】

    Object.key(obj)

    【举例】

    function Person(){};
    Person.prototype.name = "Bob";
    var person1 = new Person();
    person1.age = 20;
    person1.sex = "male";
    //定义age属性不可枚举
     Object.defineProperty(person1,"age",{
        enumerable:false
     });
    console.log(Object.keys(person1));//["sex"]

    person1对象有原型属性name,实例属性age和sex,其中age属性不可枚举。Object.keys()返回了只包含可枚举的实例属性sex的字符串数组。

    Object.getOwnPropertyNames()方法

    【定义】

    返回包含所有实例属性的字符串数组,无论是否可枚举。(关键词:实例属性、无论是否可枚举)

    function Person(){};
    Person.prototype.name = "Bob";
    var person1 = new Person();
    person1.age = 20;
    person1.sex = "male";
    //定义age属性不可枚举
     Object.defineProperty(person1,"age",{
        enumerable:false
     });
    console.log(Object.getOwnPropertyNames(person1));//["age",sex"]

    person1对象有原型属性name,实例属性age和sex,其中age属性不可枚举。Object.getOwnPropertyNames()返回了包含实例属性sex和age的字符串数组。

    拓展:

    1)constructor属性为不可枚举属性;

    2)delete操作符可以用来删除实例属性,从而让我们可以重新访问原型中的属性。

  • 相关阅读:
    GC(垃圾分代收集)
    排序算法总结
    Redis中的数据结构
    事务的隔离性(续篇)
    手写Spring mvc框架 (二)
    MySql日志与事务的隔离级别
    手写Spring mvc框架 (一)
    IO流
    随笔三(Ajax)
    关于博主noble_
  • 原文地址:https://www.cnblogs.com/youhong/p/6857563.html
Copyright © 2020-2023  润新知