阮一峰 JavaScript OOD 三部曲:

封装

JS 是一种基于对象(object-based)的语言. 但是JS不是一种真正的OOP语言, 因为语法中没有class.

以下就是简单的封装. 把两个属性封装在一个对象里面. 但是,这样的写法有缺陷.

1. 如果要多生成几个实例,写起来就非常麻烦.

2. 实例与原型之间,没有任何办法看出联系.

<script>
var Cat = {
name: '',
color: ''
}
var cat1 = {};
cat1.name = '黑猫';
cat1.color = '黑色'; var cat2 = {
name: '白猫',
color: '白色'
};
console.log(cat1);
console.log(cat2);
</script>

改进方法

我们可以写一个函数, 来解决代码重复的问题.

<script>
function dog(name, color) {
return {
name: name,
color: color
}
}
var dog1 = dog('二狗子','黑色');
var dog2 = dog('狗蛋儿','黄色'); console.log(dog1);
console.log(dog2);
</script>

构造函数

JS的构造函数和传统编程语言不同. 所谓"构造函数",其实就是一个普通函数, 但是内部可以使用this变量(JS this变量随笔), 并且this 变量会绑定在实例对象上. 只需要把function 名字首字母大写就来代表这个function是constructor

通过构造函数, 我们现在原型就可以这么写了:

    <script>
function Dog(name, color) {
this.name = name;
this.color = color;
}
var dog1 = new Dog('二狗子', '黑色');
var dog2 = new Dog('狗蛋儿', '黄色'); console.log(dog1);
console.log(dog2);
console.log(dog1.constructor === Dog); // true
          console.log(dog2.constructor === Dog); // true
      console.log(dog1 instanceof Dog); // true
      console.log(dog2 instanceof Dog); // true
</script>

构造函数的问题

构造函数方法很好用,但是存在一个浪费内存的问题. e.g.

这么做有一个弊端就是 property type 和 function eat()都是一模一样的内容, 每次生成一个实例, 都必须为重复的内容, 会多次占用内存. 这样缺乏效率和内存管理.

我们有办法像.NET 中引用类型的用法, 指向内存地址,从而节约内存使用.  这个方法就是prototype.

<script>
function Dog(name, color) {
this.name = name;
this.color = color;
this.type = '犬类';
this.eat = function() {console.log('啥都吃');};
}
var dog1 = new Dog('二狗子', '黑色');
var dog2 = new Dog('狗蛋儿', '黄色');
console.log(dog1.type) // 犬类
dog1.eat(); // 啥都吃 console.log(dog1.eat === dog2.eat); // false
</script>

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html

prototype

JavaScript规定, 每个构造函数都有一个prototype属性, 指向另一个对象.  这个对象的所有属性和方法, 都会被构造函数实例继承.

prototype 用.NET 知识来解释, 可以认为是引用类型.  指向内存同一块

那什么时候使用prototype呢?  prototype应该储存那些在object中常被子类使用的公共类型而不经常改变的primitive和function.

使用prototype可以减少使用资源.

object里面其他的内容可以理解为值类型.

prototype chain

原型链是有OOD种继承的特性.

John 是从 Person 这个constructor中继承实例化得到的.  所以John的 __proto__ === Person.prototype // true

我们看到 __proto__ 底下还有 __proto__.  这是因为 我们Person 这个constructor的prototype 是从 object中继承实例化得到的. 所以Person的__proto__ 拥有所有object的__proto__的特性.

prototype 和 __proto__ 关系

在developer tool中, __proto__ 就是object 中的prototype property.

https://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript

Object.Create 和 新实例化的function constructor的区别

Object.Create 只需要继承first argument(此例子中的calculateAge 这个function)

  Object.Create 的benefit 是可以让开发人员把一个非常复杂继承结构转换成一个简单的形式.

  因为开发人员可以直接的控制哪些prototype需要继承. 但是function constructor 需要继承所有的父中prototype.

新实例化的function constructor需要从继承的function constructor 里面继承所有的prototype property.

// Object.create
var personProto = {
calculateAge: function() {
console.log(2016 - this.yearOfBirth);
}
}; var john = Object.create(personProto);
john.name = "John";
john.yearOfBirth = 1990;
john.job = "teacher"; var jane = Object.create(personProto, {
name: {value: 'Jane'},
yearOfBirth: {value: 1969},
job: {value: 'dev'}
});

Prototype 的验证方法

JavaScript 定义了一些方法去验证, 帮助我们使用prototype.

    <script>
var Person = function (name, yearOfBirth, job) {
this.name = name;
this.yearOfBirth = yearOfBirth;
this.job = job;
} Person.prototype.calculateAge = function () {
console.log(2016 - this.yearOfBirth);
}
Person.prototype.type = '哺乳动物'; var john = new Person('John', 1990, 'teacher');
var jane = new Person('Jane', 1969, 'designer');
var mark = new Person('Mark', 1948, 'retried');
</script>

isPrototypeOf()

这个method用来潘丹prototype对象和实例之间的关系.

console.log(Person.prototype.isPrototypeOf(john)); //true

console.log(Person.prototype.isPrototypeOf(jane)); //true

hasOwnProperty()

这个method是用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性.

console.log(john.hasOwnProperty("name")); // true

console.log(john.hasOwnProperty("type")); // false

in 运算符

in 运算符可以用来判断某个实例是否含有某个属性. 不管是不是本地属性

console.log("name" in john); // true
console.log("type" in jane); // true

JavaScript Constructor & prototype的更多相关文章

  1. 彻底搞清javascript中this, constructor, prototype

    说起这三个属性,肯定有一些同学和我一样,初学js时非常困惑,头大,一脸的迷茫.今天就来给大家彻底解决这些担心受怕的问题. 先看this this定义: this就是函数赖以执行的对象. 分析这句话: ...

  2. javascript 之 prototype 浅析

    prototype 原型 javascript 是一种 prototype based programming 的语言, 而与我们通常的 class based programming 有很大 的区别 ...

  3. Javascript: 从prototype漫谈到继承(2)

    本文同时也发表在我另一篇独立博客 <Javascript: 从prototype漫谈到继承(2)>(管理员请注意!这两个都是我自己的原创博客!不要踢出首页!不是转载!已经误会三次了!) 上 ...

  4. 在 JavaScript 中 prototype 和 __proto__ 有什么区别

    本文主要讲三个 问题 prototype 和 proto function 和 object new 到底发生了什么 prototype 和 proto 首先我们说下在 JS 中,常常让我们感到困惑的 ...

  5. Javascript中prototype属性

    prototype作为JS相对比较难理解的一个知识点,在这里发表下自己的理解. 本文将包含以下几部分内容: 1.js prototype的简单介绍, 2.js构造函数的介绍, 3.prototype的 ...

  6. js老生常谈之this,constructor ,prototype

    前言 javascript中的this,constructor ,prototype,都是老生常谈的问题,深入理解他们的含义至关重要.在这里,我们再来复习一下吧,温故而知新! this this表示当 ...

  7. Javascript中prototype属性详解 (存)

    Javascript中prototype属性详解   在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不 ...

  8. JavaScript constructor 属性详解

    对象的constructor属性用于返回创建该对象的函数,也就是我们常说的构造函数. 在JavaScript中,每个具有原型的对象都会自动获得constructor属性.除了arguments.Enu ...

  9. javascript继承—prototype最优两种继承(空函数和循环拷贝)

    一.利用空函数实现继承 参考了文章javascript继承-prototype属性介绍(2) 中叶小钗的评论,对这篇文章中的方案二利用一个空函数进行修改,可以解决创建子类对象时,父类实例化的过程中特权 ...

随机推荐

  1. log4j的参数配置(转)

    转载:log4j.properties文件各参数含义与配置   以下是配置文件log4j.properties的一些属性: log4j.rootLogger=WARN, stdout, Rlog4j. ...

  2. 利用node,跑项目。

    (前提是已经安装了node) 一.简单介绍  Vue开发|文件目录结构部署 目录结构 ├── index.html 入口页面 ├── build 构建脚本目录 │ ├── build-server.j ...

  3. 2017MySQL中文索引解决办法 自然语言处理(N-gram parser)

    问题:长期以来MYSQL搜索对于中文来说不太理想,InnoDB引擎对FULLTEXT索引的支持是MySQL5.6新引入的特性,但是用“初级”一词在“我是一名初级开发者”搜索时是无法出现结果的,原因在于 ...

  4. 如何在Power BI和Tableau之间进行选择?

    作者:Mike Gallucci 如今,当谈到商业智能(BI)分析软件时,有两个主要的行业领导者 - 微软的Power BI和Tableau.根据分析和业务平台的2018年Gartner Magic ...

  5. spring boot项目,application.properties配置文件下中文乱码解决方案

    转自:https://blog.csdn.net/qq_40408534/article/details/79831807 如以上,application.properties文件下中文乱码.发生乱码 ...

  6. NSCTF2015 逆向第五题分析

    这道题目我没有写出Exploit,因为编码时候里面几个细节处理出错.但对程序的逆向分析已完成,这里就学习一下别人写Exploit的思路.主要参考:绿盟科技网络攻防赛资料下载 0x01 题目要求 题目要 ...

  7. pytorch统计模型参数量

    用resnet50 来举例子 print("resnet50 have {} paramerters in total".format(sum(x.numel() for x in ...

  8. 搜索入门_简单搜索bfs dfs大杂烩

    dfs题大杂烩 棋盘问题  POJ - 1321 和经典的八皇后问题一样.  给你一个棋盘,只有#区域可以放棋子,同时同一行和同一列只能有一个棋子. 问你放k个棋子有多少种方案. 很明显,这是搜索题. ...

  9. 测试那些事儿—web测试方法之输入框

    一.字符型输入 (1)字符型输入框 英文全角,英文半角,数字,空或者空格,特殊字符“~!@#¥%.......&*?{}[]"特别要注意单引号和&符号.禁止直接输入特殊字符时 ...

  10. C语言--第七周作业评分(5班)

    作业链接:https://edu.cnblogs.com/campus/hljkj/CS2017-5/homework/1304 一.评分要求 要求1 完成PTA第七周所有题,总共两次题,每次12.5 ...