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操作符可以用来删除实例属性,从而让我们可以重新访问原型中的属性。

JavaScript中各存在性函数的更多相关文章

  1. [转]Javascript中的自执行函数表达式

    [转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...

  2. 深入理解javascript中的立即执行函数(function(){…})()

    投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...

  3. 使用Ajax在javascript中调用后台C#函数

    使用Ajax在javascript中调用后台C#函数 最近一段时间在紧跟一个网站的项目,数据库中用户表的UserName要求是唯一的,所以当用户选定一个用户名进行注册时要首先检查该用户名是否已被占用, ...

  4. 在javascript中关于变量与函数的提升

    在javascript中关于变量与函数的提升 一.简介 在javascript中声明变量与函数的执行步骤: 1.先预解析变量或函数声明代码,会把用var声明的变量或者函数声明的代码块进行提升操作 2. ...

  5. javascript中的立即执行函数(function(){…})()

    javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包 ...

  6. 深入理解javascript中的立即执行函数

    这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见,需要的朋友可以 ...

  7. JavaScript中的内置函数

    JavaScript中的内置函数 制作人:全心全意 在使用JavaScript语言时,除了可以自定义函数之外,还可以使用JavaScript的内置函数,这些内置函数是由JavaScript语言自身提供 ...

  8. JavaScript 中对变量和函数声明提前的演示样例

    如题所看到的,看以下的演示样例(能够使用Chrome浏览器,然后F12/或者右键,审查元素.调出开发人员工具,进入控制台console输入)(使用技巧: 控制台输入时Shift+Enter能够中途代码 ...

  9. 如何在JavaScript中使用高阶函数

    将另一个函数作为参数的函数,或者定义一个函数作为返回值的函数,被称为高阶函数. JavaScript可以接受高阶函数.这种处理高阶函数的能力以及其他特点,使JavaScript成为非常适合函数式编程的 ...

随机推荐

  1. linux上搭建nginx+php+mysql环境详细讲解

    1.mysql安装 #安装编译环境 yum install -y gcc gcc-c++ gcc-devel g++ g++-devel; yum install -y wget yum instal ...

  2. appium+python 存在多个类时,不用每次都初始化解决办法

    appium+python写自动化测试用例时,为了代码的可维护性,分成不同的类是很常见的办法, 但是在运行时,每一个类都要初始化一次,即每次都会重启应用,这很麻烦,通过__new__可进行多个类之间的 ...

  3. windows下几个方便的右键菜单

    一直在用,拷来拷去麻烦,贴这里方便自己方便大家 PSHere.reg 右键菜单打开powershell Windows Registry Editor Version 5.00 [HKEY_CLASS ...

  4. python3.6.4没有raw_input

    之前是一直在用Python2.7版本,2.7里面raw_input()和input个人认为区别在于raw_input()可以输入字符串和中文,而input()只接受数字,输入字符串就会报错. 现在用的 ...

  5. 解决TeamViewer无法按给定网络地址联系伙伴

    说明:这种现象一般是断网后DNS改变了,或者路由重启了没有重启网络配合导致的. 解决方法: 1.Windows: ipconfig /flushdns 2.Linux: /etc/rc.d/init. ...

  6. elastic-job动态添加定时任务

    在elastic-job的使用过程中,我们会遇到动态添加定时任务的时候,但是官网上面并没有对这块内容进行说明.按照我的理解以及官网上面elastic-job的框架图,ej的定时任务其实是存储在zook ...

  7. linux主机名莫名其妙变成了bogon,并解决修改为localhost

    起因:公司网络接口做了接口认证,虚拟机桥接至物理网卡无法完成认证进行网络访问,无奈之下只能讲虚拟机网络模式更改为NAT模式,更改完成之后进行ssh登录,发现主机名发生了变化. 更改NAT模式之前 [r ...

  8. JAVA的NIO的新特性和小Demo,进一步了解NIO

    1.为什么要用NIO NIO 的创建目的是为了让 Java 程序员可以实现高速 I/O 而无需编写自定义的本机代码.NIO 将最耗时的 I/O 操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地 ...

  9. android Application类的详细介绍(转)

    在代码中经常看到application这个类,一直不知道这个是干什么用的,今天刚好有点时间,所以进行了详细的学习. 一.先对它的整体概念解释: 在android源码中对他的描述是; * Base cl ...

  10. JavaScript数据结构-11.散列

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...