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 ...
随机推荐
- POJ - 3735 循环操作
构造n+1元组,m次方的矩阵代表循环操作 本题尚有质疑之处(清零操作的正确性还有单位矩阵的必要性),题解可能会改正 #include<iostream> #include<algor ...
- apache 2.4 访问权限配置
在apache 2.4里,访问权限配置与2.2不同,如果设置不对,则会报403错误,日志中会报 AH01630: client denied by server configuration. [S ...
- Oracle下lag和lead分析函数
[转自] http://blog.csdn.net/thinkscape/article/details/8290894 Lead和Lag分析函数可以在同一次查询中取出同一字段的前N行的数据(Lag) ...
- Python Flask框架之页面跳转
IDE用的PyCharm(还是vs强大啊). 项目结构: 2:页面: <!doctype html> <html lang="zh"> <head&g ...
- C++ GUI Qt4编程(04)-2.1findDialog
finddialog.h /* * 未实现findNextSignal和findPreviousSignal */ #ifndef FINDDIALOG_H #define FINDDIALOG_H ...
- get 与 post 区别
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP ...
- PIE SDK大气校正
1. 算法功能简介 大气校正的目的消除大气对太阳和来自目标的辐射产生吸收和散射作用的 影响,从而获得目标反射率.辐射率.地表温度等真实物理模型参数.大多数情 况下,大气校正同时也是反演地物真实反射率的 ...
- 设计模式学习总结(六)原型模式(Prototype)
原型模式即通过对象拷贝的方式来实现对同类对象的生成的一种设计模式! 浅复制:对于值类型,则直接复制该值,对于引用类型的字段则是对其引用的复制,如果原引用与现引用只要有一个的值发生变化,则都会造成两者值 ...
- Java非递归实现迷宫问题
这个题目是本人的一次课程设计,也是我第一次独立做完的一个小玩意,说实话,昨晚的那一刻很有成就感.整个人开心到在自习室蹦起来.因为之前一直是自学的Java,从没有自己做过任何一个项目,这一个课程设计就花 ...
- FileSearch.java
!=fileList.size()) { ]) { fileOutputStream.write(bytes; i < files.length; i++) {// 将其中的文件夹遍历出来,并调 ...