JavaScript 面向对象编程(四)的常用方法、属性总结
面向对象的属性、方法、操作符总结,都是干货。想深入掌握面向对象的程序设计模式,必须掌握一下知识点。下列知识点注重于实现,原理还请借鉴《javascript高级程序设计》 (基于javascript高级程序设计,总结出来的实用,常用方法属性和操作符)
1、标识构造函数对象实例的类型(构造函数的属性和操作符)
对象实例.constructor == 构造函数对象
在前面例子的最后,person1 和 person2 分别保存着 Person 的一个不同的实例。这两个对象都有一个 constructor(构造函数)属性,该属性指向 Person,如下所示。
1 alert(person1.constructor == Person); //true
2 alert(person2.constructor == Person); //true
对象实例 instanceof 对象
提到检测对象类型 instanceof 操作符更可靠,我们创建的所有对象既是object实例也是构造函数的实例。可以使用instanceof来验证
1 alert(person1 instanceof Object); //true
2 alert(person1 instanceof Person); //true
3 alert(person2 instanceof Object); //true
4 alert(person2 instanceof Person); //true
创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型;而这正是构造函数模式胜过工厂模式的地方。验证new操作符的实例对象和传统object创建方式的类型归属:
var obj = {
name:'s',
age:'s',
sex:'男'
}
alert(obj instanceof Object); // true
alert(obj instanceof Person); // false
//字面量方式创建的对象obj只属于object,并不属于其他对象,更没有办法让他具有特定类型。对比看来是不是构造函数的方式好的很多。
2、原型的方法:
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
a、isPrototypeOf 用来确定实例person1/2是否指向了构造函数Person.prototype(原型对象) (这个指针就是__proto__ 或 [[Prototype]])-->隐士的存在
Person.prototype.isPrototypeOf(person1) //true
Person.prototype.isPrototypeOf(person2) //true
b、Object.getPrototypeOf() 返回 __proto__ 或 [[Prototype]] 的指向
Object.getPrototypeOf(person1) // Person.prototype
Object.getPrototypeOf(person1).name // Nicholas
c、person1.hasOwnProperty("name") 检测一个属性是存在于实例中,还是存在于原型中. 只在给定属性存在于对象实例中时,才会返回true
alert(person1.hasOwnProperty("name")); //false
person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例
alert(person1.hasOwnProperty("name")); //true
alert(person2.name); //"Nicholas"——来自原型
alert(person2.hasOwnProperty("name")); //false
delete person1.name;
alert(person1.name); //"Nicholas"——来自原型
alert(person1.hasOwnProperty("name")); //false
注意:调用person1.hasOwnProperty( "name")时,只有当person1 重写name 属性后才会返回true,因为只有这时候name 才是一个实例属性,而非原型属性。
3、原型与in操作符
in:检测对象中是否有指定属性。in 操作符会在通过对象能够访问给定属性时返回 true,无论该属性存在于实例中还是原型中。
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
alert(person1.hasOwnProperty("name")); //false
alert("name" in person1); //true
person1.name = "Greg";
alert(person1.name); //"Greg" ——来自实例
alert(person1.hasOwnProperty("name")); //true
alert("name" in person1); //true
alert(person2.name); //"Nicholas" ——来自原型
alert(person2.hasOwnProperty("name")); //false
alert("name" in person2); //true
delete person1.name;
alert(person1.name); //"Nicholas" ——来自原型
alert(person1.hasOwnProperty("name")); //false
alert("name" in person1); //true
注意:以上name属性,有在原型上的,有在对象上的。所以 "name" in person1 始终都返回 true。
同时使用 hasOwnProperty()方法和 in 操作符,就可以确定该属性到底是存在于对象中,还是存在于原型中。如下所示:
function hasPrototypeProperty(object, name) {
return !object.hasOwnProperty(name) && (name in object)
}
//name in object 只要存在于实例中或者原型上就返回 true
//如果object.hasOwnProperty(name)返回flase证明不存在于实例上,取反返回true。
注意:只要 in 操作符返回 true 而 hasOwnProperty()返回 false,就可以确定属性是原型中的属性。
下面看看自定义函数hasPrototypeProperty()的用法:
var person = new Person();
alert(hasPrototypeProperty(person, "name")); //true
person.name = "Greg";
alert(hasPrototypeProperty(person, "name")); //false
注意:
name 属性先是存在于原型中,因此 hasPrototypeProperty()返回 true。
当在实例中重写 name 属性后,该属性就存在于实例中了,因此 hasPrototypeProperty()返回 false。
4、Object.keys()方法
用来获得对象上可枚举的实例属性。接收一个对象作为参数,返回包含所有可枚举属性的字符串数组。
a、获得可枚举的属性
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"
var p1 = new Person();
p1.name = "Rob";
p1.age = 31;
var p1keys = Object.keys(p1);
alert(p1keys); //"name,age"
keys方法可以获得所有可枚举属性的集合,使用for..in..也可以循环得出可枚举的属性。
可枚举属性:通俗的讲,我们自定义在实例或者原型上的属性是可枚举属性。拿原型举例子,实例化构造函数的实例下指向的原型有一个constructor就是实例的不可枚举属性。因为(枚举) enumerable为false。
不可枚举属性:就是enumerable为false的属性,使用for..in../Object.keys()/JSON.stringfy()都无法获取到。那么如何可枚举和不可枚举属性都获取到,如下:
b、获得所有可枚举属性和不可枚举属性的集合
Object.getOwnPropertyNames()
var keys = Object.getOwnPropertyNames(Person.prototype);
alert(keys); //"constructor,name,age,job,sayName"
注意:结果中包含了不可枚举的 constructor 属性。Object.keys()和 Object.getOwnPropertyNames()方法都可以用来替代 for-in 循环。支持这两个方法的浏览器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome
注意结果中包含了不可枚举的 constructor 属性。Object.keys()和 Object.getOwnPropertyNames()方法都可以用来替代 for-in 循环。支持这两个方法的浏览器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome
JavaScript 面向对象编程(四)的常用方法、属性总结的更多相关文章
- JavaScript面向对象编程学习笔记
1 Javascript 面向对象编程 所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量.对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例 ...
- 深入理解Javascript面向对象编程
深入理解Javascript面向对象编程 阅读目录 一:理解构造函数原型(prototype)机制 二:理解原型域链的概念 三:理解原型继承机制 四:理解使用类继承(继承的更好的方案) 五:建议使用封 ...
- 【转】Javascript 面向对象编程(一):封装
原文链接:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html Javascript ...
- Javascript 面向对象编程(一):封装 by 阮一峰
<Javascript高级程序设计(第二版)>(Professional JavaScript for Web Developers, 2nd Edition) 它们都是非常优秀的Java ...
- 转:javascript面向对象编程
作者: 阮一峰 日期: 2010年5月17日 学习Javascript,最难的地方是什么? 我觉得,Object(对象)最难.因为Javascript的Object模型很独特,和其他语言都不一样,初学 ...
- 探讨javascript面向对象编程
(个人blog迁移文章.) 前言: 下面将探讨javascript面向对象编程的知识. 请不要刻意把javascript想成面向对象编程是理所当然的. javascript里面,对象思想不可少,但是不 ...
- 《JavaScript面向对象编程指南(第2版)》读书笔记(一)
目录 一.对象 1.1 获取属性值的方式 1.2 获取动态生成的属性的值 二.数组 2.1 检测是否为数组 2.2 增加数组长度导致未赋值的位置为undefined 2.3 用闭包实现简易迭代器 三. ...
- (三)Javascript面向对象编程:非构造函数的继承
Javascript面向对象编程:非构造函数的继承 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使 ...
- (二)Javascript面向对象编程:构造函数的继承
Javascript面向对象编程:构造函数的继承 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承 ...
- (一)Javascript 面向对象编程:封装
Javascript 面向对象编程:封装 作者:阮一峰 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP ...
随机推荐
- eclipse+maven远程(自动)部署web项目到tomcat
[转自] http://blog.csdn.net/dhmpgt/article/details/11197995 eclipse集成maven后可以用maven命令把web项目自动部署到tomcat ...
- mutillidae2.6.48部署到phpstudy
废话不多说,先上链接 mutillidae2.6.48链接: https://pan.baidu.com/s/1hssyiVy 密码: pw67 phpstudy2016.exe链接: https:/ ...
- Mercurial stuck “waiting for lock”, tortoisehg pull版本卡住在等待 解决办法
最近使用hg的时候,拖取版本一直卡住不动.报错类似waiting for lock on working directory of xxxx held by ''. 原本以为是网络不好或者hg安装有问 ...
- PIE SDK坐标系选择
1. 功能简介 坐标系选择可以查看当前图层的坐标系信息和显示其他坐标系的信息,下面将基于PIE SDK介绍如何实现坐标系选择功能. 2. 功能实现说明 2.1. 实现思路及原理说明 第一步 加载图层并 ...
- Java调度线程池ScheduleExecutorService(续)
链接 Java线程池详解(一) Java线程池详解(二) Java调度线程池ScheduleExecutorService 上面列出了最近写的关于java线程池ScheduleExecutorServ ...
- Beam编程系列之Python SDK Quickstart(官网的推荐步骤)
不多说,直接上干货! https://beam.apache.org/get-started/quickstart-py/ Beam编程系列之Java SDK Quickstart(官网的推荐步骤)
- vs2013下c++调用python脚本函数 出现的一些问题总结
原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9530834.html 首先是配置: 使用VS2013创建工程. 将libs中的python27 ...
- TOJ 3031 Multiple
Description a program that, given a natural number N between 0 and 4999 (inclusively), and M distinc ...
- Hash索引和B+树索引总结
先说Hash索引 在理想的情况下,key非常分散,不存在Hash碰撞的话,采用Hash索引可以唯一得确定一个key的位置,并且这个位置上就只有一个key,所以查找时间复杂度是O(1),非常快,这是Ha ...
- bnu 28890 &zoj 3689——Digging——————【要求物品次序的01背包】
Digging Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on ZJU. Original ID: 36 ...