构造函数与原型

构造函数模式

 最简单的构造函数:

function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() {
console.log(this.name);
}
} var p1 = new Person("jerry", 18, "Coder");
var p2 = new Person("tom", 28, "Javaer");

 要创建Person的实例,需要使用new关键字。以这种方式调用函数能够创建实例对象是因为使用new后会隐式地执行以下四个步骤:

  1. 创建一个新对象(基于Object的对象)
  2. 将构造函数的作用域赋给新对象(此时this就指向了新对象)
  3. 执行构造函数内的代码
  4. 返回对象

 若不使用new关键字而直接调用该函数,那它就跟普通函数一样;函数中的this就会是当前的全局作用域:

Person("jerry", 18, "Javaer"); //添加到window中
window.sayName(); // "jerry"

 实例对象都会有个constructor(实际上这个属性应该是在原型上的。下一节讲原型的概念)属性,指向构造函数:

console.log(p1.constructor == Person); //true

但不建议使用这种方式来检测对象类型,因为该属性是可写的;应使用instanceof。


原型模式

 前面说的最基本的构造函数模式有个很明显的问题就是:对于每次新创建一个实例时,都需要在实例上重新创建一个sayName函数;这样创建许多相同功能的函数对象显然是没有必要的。下面说的原型模式可以解决这种问题。

 在JS中创建的每一个函数类型都有一个prototype(原型)属性,该属性指向一个对象 即原型对象,而这个对象的用途是可以包含由某一类型的所有实例共享的属性和方法

 通过这个例子来辅助理解下原型的用途:

function Person() {
}
Person.prototype.name = "jerry";
Person.prototype.age = 18;
Person.prototype.job = "Javaer"; Person.prototype.sayName = function() {
console.log(this.name);
} var p1 = new Person();
var p2 = new Person();
p1.sayName() //"jerry"
console.log(p1.sayName == p2.sayName) //true

 通过在原型中定义变量和函数,使得该构造函数的所有实例都能共享相同的变量和函数。这是由原型搜索机制所完成的:因为每个实例对象都有个内部属性[[prototype]]指向原型对象;当搜索对象的某个属性时,会先搜索实例对象本身,如果有则返回;没有的话就会到[[prototype]]指针指向的原型中继续寻找。 因此,在实例对象中可以覆盖原型中的同名属性。 而且,所有实例对象指向的都是同一个原型,这也就是为什么上面代码中实例对象都有相同的变量和函数。

 需要注意一点,实例对象的[[prototype]]是在创建对象初由构造函数的prototype属性赋值来的;所以 如果在创建完实例对象后重写原型的话,重写后的原型是与先前创建的实例对象无关的(实例对象仍指向原来的那个原型):


function Person() {
}
Person.prototype = {
constructor: Person,
name : "Tom"
}
var p = new Person();
console.log(p.name); //"Tom" Person.prototype = {
constructor: Person,
name: "jerry",
age: 18,
job: "Javaer",
sayName: function() {
console.log(this.name);
}
} console.log(p.name); //"Tom" p.sayName(); //throw error

寄生构造函数模式

 名字起的有些奇怪,其实就是指封装显式创建对象的过程,然后再返回新创建的对象。

function Person() {
var o = new Object();
o.name = "Java";
o.f = function() {
console.log("Kotlin");
}
return o;
} var temp = new Person();
console.log(temp.name); //"Java"
temp.f(); //"Kotlin"

 这里使不使用new操作符都没有影响,两者效果是一样的。使用了new,构造函数在无返回值的情况下,默认返回隐式创建的新实例对象。而在构造函数中添加return语句,可以重写调用构造函数时返回的值。



 这种模式本质上讲就是用个普通函数 在其中对已有对象进行添加或重写属性 以达到增强已有对象的功能;还有点类似于继承的作用。

创建一个自定义的Array对象:

function myArray() {
var arr = new Array(); arr.push.apply(arr, arguments); arr.toString = function() {
return this.join("|");
} return arr;
} var colors = myArray("red", "blue", "yellow");
console.log(colors.toString()); //"red|blue|yellow"

稳妥构造函数模式

 这一节的内容在红宝书上放的位置感觉是不太合适的=_= ... 对于初学者看这节的内容可能会有点迷,而且书上给的例子的代码也不全。 书上阐述的这种模式的作用 主要就是为了构造没有公共属性的对象,即模拟 私有变量,仅能通过函数访问。 建议可以跳过这一节的内容,在之后明白了闭包的概念后可以再回来看下这节内容。

《Javascript高级程序设计》读书笔记——构造函数与原型的更多相关文章

  1. Javascript高级程序设计--读书笔记之理解原型对象

    先上一段代码和关系图 function Person(){} Person.prototype.name = "Nic" Person.prototype.age = 22 Per ...

  2. JavaScript高级程序设计-读书笔记(2)

    第6章 面向对象的程序设计 创建对象 1.最简单方式创建Object的实例,如 var person = new Object(); person.name = “Greg”; person.age ...

  3. javascript高级程序设计读书笔记-事件(一)

    读书笔记,写的很乱   事件处理程序   事件处理程序分为三种: 1.html事件2. DOM0级,3,DOM2级别  没有DOM1 同样的事件 DOM0会顶掉html事件   因为他们都是属性  而 ...

  4. Javascript高级程序设计--读书笔记之面向对象(一)

    哈哈哈万物皆对象,终于到了js的面向对象篇. 一.属性类型 (1)数据属性 数据属性包含一个数据值的位置,在这个位置可以写入和读取数值,数据属性有四个描述器行为的特性 [[Configurable]] ...

  5. javascript高级程序设计读书笔记

    第2章  在html中使用javascript 一般都会把js引用文件放在</body>前面,而不是放在<head>里, 目的是最后读取js文件以提高网页载入速度. 引用js文 ...

  6. Javascript高级程序设计读书笔记(第六章)

    第6章  面向对象的程序设计 6.2 创建对象 创建某个类的实例,必须使用new操作符调用构造函数会经历以下四个步骤: 创建一个新对象: 将构造函数的作用域赋给新对象: 执行构造函数中的代码: 返回新 ...

  7. JavaScript高级程序设计-读书笔记(7)

    第22章 高级技巧 1.高级函数 (1)安全的类型检测 在任何值上调用Object原生的toString()方法,都会返回一个[object NativeConstructorName]格式的字符串. ...

  8. javascript高级程序设计读书笔记----面向对象的程序设计

        创建对象   工厂模式 function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = ...

  9. javascript高级程序设计 读书笔记1

    第二章  在HTML中使用JS 加载JS有三种:行内,head头部和外部链接JS   最好使用外部链接<script src="example.js" ></sc ...

  10. JavaScript高级程序设计-读书笔记(6)

    第20章 JSON JSON是一个轻量级的数据格式,可以简化表示复杂数据结构的工作量 JSON的语法可以表示一下三种类型的值 l        简单值:使用与JavaScript相同的语法,可以在JS ...

随机推荐

  1. 揭开KPI异常检测顶级AI模型面纱

    摘要:2020GDE全球开发者大赛-KPI异常检测告一段落,来自深圳福田莲花街道的"原子弹从入门到精通"有幸取得了总榜TOP1的成绩,在这里跟大家分享深圳福田莲花街道在本次比赛的解 ...

  2. 当物联网遇上云原生:K8s向边缘计算渗透中

    摘要:K8s正在向边缘计算渗透,它为边缘侧的应用部署提供了便利性,在一定程度上转变了边缘应用与硬件之间的关系,将两者的耦合度降低. 本文分享自华为云社区<云原生在物联网中的应用[拜托了,物联网! ...

  3. 一起玩转LiteOS组件:Pixman

    摘要:本文将以Pixman Demo为例,详细说明Pixman的功能. 本文分享自华为云社区<LiteOS组件尝鲜-玩转Pixman>,作者:Lionlace. 基本介绍 Pixman是由 ...

  4. APP 备案公钥、签名 MD5、SHA-1、SHA-256获取方法。

    ​ 公钥和 MD5 值可以通过苹果开发工具.Keytool.appuploder 等多种工具获取,最简单的就是以 appuploader为例. 1.下载 appuploader工具 ,点击此处 下载 ...

  5. 火山引擎数智平台拆解 APP改版场景中蕴含的数据思维

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 你有没有遇到过,打开一款经常使用的 APP,它却跳出一条需要你升级版本的提示? 大多数情况下,用户可能会直接点击「 ...

  6. PPT 没有电脑如何制作PPT

    没有电脑如何制作PPT

  7. 解决ttrss(Tiny Tiny RSS)中fever无法使用的问题

    问题描述 在ttrss刚搭建好的时候,进行了如下操作: 随后键入了密码(fever密码) 最后,按照官方给的提示,在Fluent Reader中测试,弹出如下错误信息: 解决方案 复制官方给的链接,删 ...

  8. POJ 2726、POJ3074 :数独(二进制DFS)

    题目链接:https://ac.nowcoder.com/acm/contest/1014/B 题目描述 In the game of Sudoku, you are given a large 9 ...

  9. 嵌入式Linux必读经典书籍(含下载方式)

    最近,在知乎看到一个问题,"嵌入式Linux有哪些好书推荐".我读研期间也喜欢收藏一些书籍,每次看到京东有活动,总是忍不住想买一些书籍回来. 随着时间越来越久,我买的书越来越多,但 ...

  10. 密码加密bcrypt