构造函数与原型

构造函数模式

 最简单的构造函数:

  1. function Person(name, age, job) {
  2. this.name = name;
  3. this.age = age;
  4. this.job = job;
  5. this.sayName = function() {
  6. console.log(this.name);
  7. }
  8. }
  9. var p1 = new Person("jerry", 18, "Coder");
  10. var p2 = new Person("tom", 28, "Javaer");

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

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

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

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

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

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

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


原型模式

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

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

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

  1. function Person() {
  2. }
  3. Person.prototype.name = "jerry";
  4. Person.prototype.age = 18;
  5. Person.prototype.job = "Javaer";
  6. Person.prototype.sayName = function() {
  7. console.log(this.name);
  8. }
  9. var p1 = new Person();
  10. var p2 = new Person();
  11. p1.sayName() //"jerry"
  12. console.log(p1.sayName == p2.sayName) //true

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

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


  1. function Person() {
  2. }
  3. Person.prototype = {
  4. constructor: Person,
  5. name : "Tom"
  6. }
  7. var p = new Person();
  8. console.log(p.name); //"Tom"
  9. Person.prototype = {
  10. constructor: Person,
  11. name: "jerry",
  12. age: 18,
  13. job: "Javaer",
  14. sayName: function() {
  15. console.log(this.name);
  16. }
  17. }
  18. console.log(p.name); //"Tom"
  19. p.sayName(); //throw error

寄生构造函数模式

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

  1. function Person() {
  2. var o = new Object();
  3. o.name = "Java";
  4. o.f = function() {
  5. console.log("Kotlin");
  6. }
  7. return o;
  8. }
  9. var temp = new Person();
  10. console.log(temp.name); //"Java"
  11. temp.f(); //"Kotlin"

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



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

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

  1. function myArray() {
  2. var arr = new Array();
  3. arr.push.apply(arr, arguments);
  4. arr.toString = function() {
  5. return this.join("|");
  6. }
  7. return arr;
  8. }
  9. var colors = myArray("red", "blue", "yellow");
  10. 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. 当AI抄起了水表

    摘要:一套AI工作流,既减轻水表抄表工的负担,也保证了普通百姓用水数据的真实. 本文分享自华为云社区<行业案例:当AI抄起水表,一套工作流打通水务智能的"任督二脉">, ...

  2. 使用appuploader工具发布证书和描述性文件教程

    使用APPuploader工具发布证书和描述性文件教程 之前用AppCan平台开发了一个应用,平台可以同时生成安卓版和苹果版,想着也把这应用上架到App Store试试,于是找同学借了个苹果开发者账号 ...

  3. 火山引擎DataTester:如何使用A/B测试优化全域营销效果

      当前,营销技术步入了全渠道.全周期的全域时代,随着广泛的数据积累,数据科学技术在营销领域发挥着越来越重要的作用,从消费者人群洞察到智能化信息广告投放,营销的提效让企业得以在转化的每个环节提升影响力 ...

  4. POJ:3279-Fliptile【状态压缩】【DFS】

    POJ-3279 经典[状态压缩][DFS]题型 题目大意:有一个 M * N 的格子,每个格子可以翻转正反面,它们有一面是黑色,另一面是白色.黑色翻转之后变成白色,白色翻转之后则变成黑色. 游戏要做 ...

  5. 活动回顾|阿里云 Serverless 技术实战与创新成都站回放&PPT下载

    7月29日"阿里云 Serverless 技术实战与创新"成都站圆满落幕.活动受众以关注 Serverless 技术的开发者.企业决策人.云原生领域创业者为主,活动形式为演讲.动手 ...

  6. 什么是全同态加密(FHE)中的自举(Bootstrapping)?

    PrimiHub一款由密码学专家团队打造的开源隐私计算平台,专注于分享数据安全.密码学.联邦学习.同态加密等隐私计算领域的技术和内容. 全同态加密(Fully Homomorphic Encrypti ...

  7. 【教你学Qt桌面端开发】pt1:浅谈Qt:特色C++主义类库

    还在为头脑简单看不懂代码而发愁吗?还在为思想浅薄只会人云亦云.拾人牙慧.鹦鹉学舌而遭人鄙夷吗? <教你写代码>,从另一维度解读代码,让你成为见解独特的黑马观众. 教你学Qt桌面端开发栏目旨 ...

  8. 4.Prometheus之存储及WAL

    一.整体介绍 二.block 2.1 head block 三.WAL(Write-ahead logging, 预写日志) 3.1 数据流向 四.和存储相关的启动参数 五.总结 一.整体介绍 Pro ...

  9. Cortex M3 CORE

    Cortex CM3 内核架构 CM3内核主要包含几个部分:取指(Fetch)\指令译码(Decoder/DEC)\执行(EXEC)\ALU 内存取数通过load & store指令,就是通过 ...

  10. 1. 在Windows10上使用dbca配置oracle19.3.0.0时,报错DBT-50000 无法检查可用内存。

    1.如图所示,在安装过程中,我遇到了错误提示,无法检查可用内存,导致安装失败. 在咨询后,认为是内存不足导致的问题,便清理了内存,重新安装.但是依旧出现以上内容,检查自己的内存大小,远远大于其安装所需 ...