构造函数与原型

构造函数模式

 最简单的构造函数:

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. 中企出海,用火山引擎DataTester开启增长第一步

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   今年 Google 宣布其提供的A/B测试工具 Optimize 将在2023年9月30号停止服务.在全球化浪 ...

  2. 手把手教你在 Windows 环境中搭建 MQTT 服务器

    前言 前些天要对接一家硬件商的设备数据,对方使用的 MQTT 协议点对点透传,所以又赶紧搭建 MQTT 服务器,写 .NET 程序接收数据等等,今天分享一下如何搭建 MQTT 服务器. MQTT 协议 ...

  3. 【申请教程】ChatGPT访问互联网插件

    https://openai.com/blog/chatgpt-plugins 大家好,我是章北海mlpy 申请ChatGPT插件很久了,一直没下文 最近看到两种套路,我早上试了一下,看能否快速成功吧 ...

  4. AI 视频云 VS 窄带高清,谁是视频时代的宠儿

    随着网络技术的逐渐改善,各类视频消息成为媒体传播的主要选择手段.但其实支撑着视频传播的并不单单是网络技术,还有视频转码与压缩技术.这类技术下分很多,比如曾经被频繁提到的 H.265,比如时下热门的窄带 ...

  5. Go--append()

    作用:在原切片的末尾添加元素 实例: package main import "fmt" func main() { s1 := []int{} fmt.Printf(" ...

  6. 未来,让我们一起想象 — “Imagine” 阿里云视频云全景创新峰会

    视频云赛道是一条极具想象力的赛道,可以变革商业与社会,成为大视频时代底座. 视频云技术是一项极具创新力的技术,可以突破时间与空间,创造一个全新的世界. 7 月 10 日,"Imagine&q ...

  7. Java 使用 slf4j + log4j 写日志

    没有SpringBoot等框架的情况下 pom.xml: <properties> <slf4j.version>1.7.26</slf4j.version> &l ...

  8. POJ - 1611 : The Suspects (普通并查集)

    思路: 模板题,一步一步加入集合,最后判断有多少人跟0在同一个集合就行了. #include<iostream> #include<cstdio> using namespac ...

  9. Codeforces Round #715 (Div. 2) (A~D 补题记录)

    补题链接:Here 经典手速场 1509A. Average Height 题意:要找出最大不平衡对序列 先输出奇数,然后输出偶数 void solve() { int n; cin >> ...

  10. debian更新openssh 9.6

    先更新一下,然后安装libssl-dev zlib1g-dev依赖文件 apt update apt install build-essential apt-get install -y libssl ...