<读书笔记>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页),读起来 ...
随机推荐
- svg画圆环
之前我已经分享了一篇css画圆环,为啥今天还要分享一篇svg画圆环呢? 原因是:css画圆环在部分ipone手机会有bug,最大张角为90°,所以圆环会有白色的间隙. 好了,开始代码展示: html: ...
- Kernel Page Global Directory (PGD) of Page table of Process created in Linux Kernel
Kernel Page Global Directory (PGD) of User process created 在早期版本: 在fork一个进程的时候,必须建立进程自己的内核页目录项(内核页目录 ...
- 702:Crossing River (贪心)
[题目描述] N个人过河,一次过去2个回来一个,给出每个人所需时间,问最小过河时间. [题目链接] http://noi.openjudge.cn/ch0406/702/ [算法] 一开始想样例是怎么 ...
- CodeForces 295B Greg and Graph (floyd+离线)
<题目链接> 题目大意:给定$n$个点的有向完全带权图$(n\leq500)$,现在进行$n$次操作,每次操作从图中删除一个点(每删除一个点,都会将与它相关联的边都删除),问你每次删点之前 ...
- C# Base64编码解码 ,Md5、Rsa加密解密
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Clas ...
- git_clone资源获取失败解决
github上克隆一个仓库到本地,一直失败.还以为是git安装问题,卸载重装无效:又换了个大容量的磁盘目录位置:最后ECS系统也重装还是无效.. remote: Counting objects: 5 ...
- 安装Sublime Text 3 的过程
在Sublime Text官网下载最新的APP https://www.sublimetext.com 我下载的是 3143 安装之后开始在网上找注册码 我用了成功的注册码的是 这个应该是单个用户的, ...
- 【记录】mysql 查看某数据库各个表容量大小SQL
有时候我们可能需要了解数据库中各个表的容量及大小,好了解数据库情况. 现只需要一条SQL就可以直观的展示出来. SELECT table_schema AS '数据库', table_name AS ...
- 大哥带我走渗透8--CSRF的应用
1.大哥给了一个CSRF实战视频,真的很简单,但是我今天晚上有点不在状态,很多简单的问题也没有想.所以做了一个多小时.这件事给我的启发就是,无论发生什么事,都不要影响自己的学习.先写点废话,真的真的, ...
- Codeforces Round #392 (Div. 2) - C
题目链接:http://codeforces.com/contest/758/problem/C 题意:给定N*M矩阵的教室,每个位置都有一个学生,Sergei坐在[X,Y],然后老师会问K个问题,对 ...