<读书笔记>JavaScript系列之7种创建对象(面向对象)
写在前面:
以下三选一:
- 阅读博文JavaScript 对象详解.
- 阅读《JavaScript权威指南》第6章。
- 阅读《JavaScript高级程序设计》第6章。
- 注意:只需要看“理解对象”(Understanding Objects)部分。
6.2 创建对象
6.2.1 工厂模式
- 创建多个相似对象的问题,代码实现
function createPerson(name, age, job) {
var o = new Object(); //关键之一
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
};
return o; // 关键之二
}
var person1 = createPerson("tianyuan", 22, "web-front-end");
var person2 = createPerson("zhangsen", 21, "analysis");
alert(person1.name);
alert(person2.sayName());
6.2.2 构造函数模式
三个特点:
- 1.没有显示地创建对象
- 2.直接将属性和方法赋给了this对象
- 3.没有return语句
- ⚠️注意:构造函数命名:开头大写
代码实现:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() {
alert(this.name);
};
}
var person1 = new Person("tianyuan", 22, "web-front-end");
var person2 = new Person("zhangsen", 21, "analysis");
console.log(person1.name);
console.log(person2.sayName());
alert(person1.constructor == Person);
alert(person2.constructor == Person);
alert(person1 instanceof Object); // 检查person1是否是否为Objetct的实例, Objetct注意首位大写
alert(person1 instanceof Person); // 检查person1是否是否为Person的实例
alert(person2 instanceof Object); // 检查person2是否是否为Objetct的实例, Objetct注意首位大写
alert(person2 instanceof Person); // 检查person2是否是否为Person的实例
6.2.3 原型模式
每个函数都有一个prototype(原型)属性.
1.prototype:
- 这个属性是一个指针: [[Prototype]];
- 通过调用构造函数而创建的那个对象实例的原型对象
- 使用其的好处是: 可以让所有对象实例共享它所包含的属性和方法.
- 也就是说:不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中.
- 与构造函数不同的是: 其新对象的这些属性和方法是由所有实例共享的.
- 这里需要理解原型对象,才能理解这种模式的原理.
- __ proto __
- p148 图解,秒懂
- 原理: 原型对象是真实存在的,而person1,person2的prototype则是以虚拟的指针形式来引用真实的原型对象以达到共享属性和方法的目的.
- isPrototypeOf()用来确定对象之间是否存在这种原型关系.
- Object.getPrototypeOf,这个方法返回:[[Prototype]](ECMAScript 5 新增的方法)
- delete操作符,实例属性会屏蔽原型中的同名属性,除非使用delete操作符删掉实例属性.
- hasOwnProperty: 实例属性返回true, 原型属性则返回false
2.in操作符与原型
- in操作符: alert("name" in person); //true or false
- hasPrototypeProperty()函数
- in: IE早期版本 bug
- Object.keys()
- Object.getOwnPropertyNames(): 无论是否可以枚举,可得到所有实例属性.
- 15,16皆可代替for-in循环枚举
3.更简单的原型语法:
- 提取prototype至于person后() {},代码如下
- 简单版的字面量创建对象的方法会导致constructor不再指向Person
- 通过设定将constructor值改为: Person后,会导致它的[[Enumerable]]被设置为true.
- 重设构造函数(只适用于ECMAScript兼容的浏览器)
function Person() {
}
Person.prototype = {
name : "tianyuan",
age : 29,
job: "web",
sayName: function() {
alert(this.name);
}
};
4.原型的动态性
5.原生对象的原型
- 可自定义方法:startWith()
6.原型对象的问题:
- 共享的话,一旦改,则全变,从而无法单独使用此模式,需要结合构造函数模式.
代码实现:
function Person() {
}
Person.prototype.name = "tianyuan";
Person.prototype.age = 29;
Person.prototype.sayName = function() {
alert(this.name);
}
var person1 = new Person();
var person2 = new Person();
person1.sayName();
person2.sayName();
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" 可枚举属性
// 在此种模式中,false问题得以解决;且新对象的这些属性和方法是由所有实例共享的.
alert(person1.sayName == person2.sayName); //true
6.2.4 组合使用构造函数模式和原型模式
这是结合两种模式的长处所成的一个成熟模式
优点:
- 每个实例都会有自己的一份实例属性的副本
- 同时又共享着对方法的引用
- 最大限度地节省了内存。
代码实现:
// 混合模式重写例子
// 这是目前ECMAScript中使用最广泛,认同度最高的一种创建自定义类型的方法,可以说是定义引用类型的默认模式.
function Person(name, age, job) {
this.name = name;
this.job = job;
this.age = age;
this.friends = ["tianyuan", "zhangsen"];
}
Person.protptype = {
constructor : Person, // 指向Person原型
sayName : function() {
alert(this.name);
}
};
var person1 = new Person("tianyuan", 22, "web-front-end");
var person2 = new Person("zhangsen", 21, "analysis");
person1.friends.push("Van");
alert(person1.friends); // tianyuan,zhangsen,Van
alert(person2.friends); // tianyuan,zhangsen
alert(person1.friends === person2.friends); // false
alert(person1.sayName === person2.sayName); // true
6.2.6 寄生构造函数模式
代码实现类似于: 工厂模式与构造函数模式的结合体
总的来说,建议在可以使用其它模式的情况下,不要使用此模式.
instanceof 操作符对此对象无意义
代码实现:
function Person(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
};
return o;
}
var friend = new Person("tianyuan", 18, "web");
friend.sayName(); // tianyuan*/
// 这个模式可以在特殊的情况下用来为对象创建构造函数.(因为不能直接修改Array构造函数)
function SpecifialArray() {
// 创建数组
var values = new Array();
// 添加值
values.push.apply(values, arguments);
// 添加方法
values.toPipedString = function() {
return this.join("|");
};
// 返回数组
return values;
}
var colors = new SpecifialArray("red", "ok", "blue");
alert(colors.toPipedString()); // "red|ok|blue"
6.2.7 稳妥构造函数模式
所谓的稳妥对象: 没有公共属性,且其方法也不引用this的对象.
稳妥对象最适合在一些安全的环境中(禁止使用this or new),或者在防止数据被其它应用程序改动时使用.
稳妥构造函数是与寄生构造函数类似的模式,但有2点不同: (1)新创建对象的实例方法不引用this. (2)不使用new操作符调用构造函数
变量friend中保存的是一个稳妥对象,且instanceof 操作符对此对象无意义
⚠️: 这种模式下,除了使用sayName()外,没有其它办法访问name值.
代码实现:
function Person(name, age ,job) {
var o = new Object();
// 可以在这里定义私有变量和函数
// 添加方法
o.sayName = function() {
alert(name);
}
// 返回对象
return o;
}
var friend = Person("tianyuan", 18, "web");
friend.sayName(); // tianyuan
定义访问器属性(新法)
var book = {
_year: 2004,
edition: 1
};
Object.defineProperty(book, "year", {
get: function() {
return this._year;
},
set: function(newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
});
book.year = 2005;
alert(book.year);
alert(book.edition);
定义访问器属性(旧法)
var book = {
_year: 2004,
edition: 1
};
// 定义访问器的旧方法
book.__defineGetter__("year", function() {
return this._year;
});
// _ _ , 俩
book.__defineSetter__("year", function(newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
});
book.year = 2005;
alert(book.year);
alert(book.edition);
Object.defineProperties
- 定义多个属性(合起来)
var book = {};
Object.defineProperties(book, {
_year: {
value: 2004
},
edition: {
value: 1
},
year: {
get: function() {
return this._year;
},
set: function(newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
}
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value);
alert(descriptor.configurable);
alert(typeof descriptor.get);
var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value);
alert(descriptor.configurable);
alert(typeof descriptor.get);
对象字面量创建对象
// 对象字面量创建对象
var person = {
name: "TianYuan",
age: "22",
job: "web-front-end",
sayName: function() {
alert(this.name);
}
};
alert(person.name);
alert(person.age);
alert(person.sayName());
【Javascript高级程序设计 】
第三版
p25
对未经声明变量调用delete不会导致错误?
p27
布尔类型:0,NaN,null,undefined会转化为false
p29
Number.MAX_VALUE==1.7976931348623157e+308。Infinity。
isFinite()
isNaN()
Number()
parseInt()指定基数,
parseFloat()
p34拼接字符串过程
toString()
p37
var num1=2;
var num2=20;
var num3=num1-- + num2;//等于22
var num4=num1 + num2;//等于21
p38
一元操作符 a=+a //a
一元操作符 b=-b //-b
p40-26
p42按位异或XOR
p43左移右移各种
Boolean()
短路操作符false
p47.8skip
p57for-in 枚举
p58label语句需配合for循环p59循环
with()
2016.03.17.08:40
p69 不能给基本类型值添加属性,只能对象
<读书笔记>JavaScript系列之7种创建对象(面向对象)的更多相关文章
- <读书笔记>Javascript系列之6种继承(面向对象)
写在前面: 以下三选一: 阅读博文JavaScript 对象详解. 阅读<JavaScript权威指南>第6章. 阅读<JavaScript高级程序设计>第6章. 注意:只需要 ...
- Chrome插件安利!可以一键导出微信读书笔记|支持Markdown等三种格式
众所周知,微信读书App 是一款非常优秀的阅读类App ,周围也有不少人在用.虽然工作比较忙.但是也没少在上面看书做笔记. 美中不足的是,目前微信读书虽然支持笔记导出,但是提供的是将笔记复制到剪切板, ...
- JS学习笔记——JavaScript继承的6种方法(原型链、借用构造函数、组合、原型式、寄生式、寄生组合式)
JavaScript继承的6种方法 1,原型链继承 2,借用构造函数继承 3,组合继承(原型+借用构造) 4,原型式继承 5,寄生式继承 6,寄生组合式继承 1.原型链继承. <script t ...
- [读书笔记]javascript语言精粹'
人比较笨,以前只做项目,案例,然而一些javascript的很多理论不知道该怎么描述,所以最近开启一波读书之旅: 标识符 1.定义 标识符以字母开头,可能后面跟上一个或多个字母.数字或者下划线. 2. ...
- 读书笔记-JavaScript面向对象编程(三)
第7章 浏览器环境 7.1 在HTML页面中引入JavaScript代码 7.2概述BOM与DOM(页面以外事物对象和当前页面对象) 7.3 BOM 7.3.1 window对象再探(所以JavaSc ...
- [读书笔记] JavaScript设计模式: 单例模式
单例模式:保证一个类只有一个实例,并提供一个可以访问它的全局访问点. 一种简单.方便的写法就是用一个变量来标识当前类是否已经创建过对象,如果有,则返回已经创建好的对象,否则创建一个新对象,并将其返回. ...
- 读书笔记-----javascript基本数据类型
由于js基础差, 记性也不好,准备一边读书一边做记录,希望这样能加深一下记忆 /* 第一天 */ javascript 基本数据类型 js一共只有五种数据类型 Undefined, Nu ...
- 读书笔记-JavaScript面向对象编程(一)
PDF下载链接: http://pan.baidu.com/s/1eSDSTVW 密码: 75jr 第1章 引言 1.1 回顾历史 1.2 变革之风 1.3 分析现状 1.4 展望未来 1.5 面向对 ...
- 《JavaScript权威指南》读书笔记——JavaScript核心
前言 这本由David Flanagan著作,并由淘宝前端团队译的<JavaScript权威指南>,也就是我们俗称的“犀牛书”,算是JS界公认的“圣经”了.本书较厚(有1004页),读起来 ...
随机推荐
- Lua中C API栈操作
向栈中压入数据: lua_pushnil(lua_State*); lua_pushboolean(lua_State*, bool); lua_pushnumber(lua_State*, lua_ ...
- [CF804F]Fake bullions
Solution: 这题可以分为两个部分, 一个部分为处理出每个点最大的金条数与最小的金条数,记为 \([Min_i, Max_i]\) 第二部分为对于 \(n\) 个变量 \(x_i\i ...
- 分布式ID增强篇--优化时钟回拨问题
原生实现 本文承接sharding-jdbc源码之分布式ID,在这篇文章中详细介绍了sharding-jdbc的分布式ID是如何实现的:很遗憾的是sharding-jdbc只是基于snowflake算 ...
- 有关css的兼容问题
兼容性 1 页面在不同浏览器中可能显示不同 在IE6下 子级的宽度会撑开父级设置好的宽度 温馨提示:和模型的计算一定要精确,IE浏览器可能显示不同 兼容性 2 在IE6中,元素浮 ...
- Codeforces Round #394 (Div. 2) - A
题目链接:http://codeforces.com/contest/761/problem/A 题意:给定a个偶数,b个奇数,问是否能构成奇偶相间的阶梯.思路:a和b相差小于等于1即可构造出来.特判 ...
- 两个对象值相同(x.equals(y)==true),hashcode也相同
不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同.Java对于eqauls方法和hashCode方法是这样规定的:(1)如果两个对象相同( ...
- 牛客网NOIP赛前集训营-提高组(第七场)B-随机生成树
题目描述 牛牛在纸上画了\(N\)个点(从\(1\)到\(N\)编号),每个点的颜色用一个整数描述. 牛牛决定用这\(N\)个点随机生成一棵树,生成的规则如下: \(1\)号点是根节点 对于\(2\) ...
- AI比医生更好地发现皮肤癌,未来计算机技术可渗透医院
未来机器人将取代医生?这可能是事实.为什么这么多年轻人选择计算机行业,因为这是一个趋势.据法新社报道,研究人员周二称,一项计算机技术比人类皮肤科医生在检测皮肤癌方面的表现要好得多,因为这项研究是为了寻 ...
- JSP相关学习
动态页面技术(JSP/EL/JSTL) <!-- jsp的三种脚本方式 --> <% int i = 5; //这是单行注释 /*这是多行注释*/ %> <%=i%> ...
- input框金额输入验证
金额输入要求:只能是数字且小数点后保留两位小数 html <input type="text" min="10" id="dc-moneyInp ...