前言:JavaScript的原型对象一直是新人学习js的一大重大阻碍,但是原型的知识往往又是面试中常常会被深挖的一个点,为什么会这样呢?本文带你揭秘JavaScript原型的重要性,了解重要性之后再进行学习效果会更佳。

1、从工厂模式说起

  众所周知,工厂模式在软件工程领域的运用极其广泛,以下举例工厂模式创建一个对象。

 1 function createCar(name,num){
2 //创建一个空对象
3 let obj = {};
4 //为空对象添加属性
5 obj.name = name;
6 obj.num = num;
7 return obj
8 }
9 const myCar = createCar('benz',123456)
10 console.log (myCar); //{name: 'benz', num: 123456}

  上述案例中,createCar()方法接收两个参数,一个name,一个num,通过参数传入,然后返回新对象,最后调用函数即可快速创建多个属性不同的对象。

  这样的好处是能够快速创建大量属性不同的对象,但是新创建的对象没有明确的标识,即无法得知新创建的对象是什么类型,使用instanceOf无法准确查明。通过构造函数可以解决标识问题并也能批量创建对象。为此,我们引出构造函数的概念。

2、构造函数模式

  ES中的构造函数是用于创建特定类型对象的,如Object和Array这样的原生构造函数,运行时就可以直接使用。但是我们也可以使用构造函数来定义属性和方法。

  以下为使用构造函数模式创建的对象的例子:

1 const Person = function(name,age){
2 this.name=name;
3 this.age=age;
4 }
5 const p1 = new Person('Billy',21);
6 console.log(p1);//{name:Billy,age:21}

  上述例子同样也可以通过多次new来创建大量属性不同的对象 ,所创建的对象与工厂模式创建的对象类似,但是仍有以下区别:

  • 没有显示创建对象
  • 属性和方法直接赋值给了this
  • 没有return
  • 解决了标识问题

  这样看似创建的对象天衣无缝,又能批量创建、又有标识,但是如果使用构造函数创建对象需要在对象上捆绑方法时,就会存在极大缺陷。代码如下:

1 const Person = function(name,age){
2 this.name=name;
3 this.age=age;
4 this.sayName(){
5 console.log(this.name)
6 }
7 }
8 const p1 = new Person('Billy',21);

  构造函数的主要问题就存在于此,构造函数定义的方法会在每个实例上都创建一遍,即每次定义函数时都会初始化一个对象。即可以看似为:

1 const Person = function(name,age){
2 this.name=name;
3 this.age=age;
4 this.sayName = new Function(){
5 "console.log(this.name)"
6 };
7 }
8 const p1 = new Person('Billy',21);

  因此,以这种方法创建函数会带来不同的作用域链和标识符解析,不同实例上函数虽然同名但是却不相等。因为都是一样的效能,所以没有必要定义两个不同的函数。

  要解决这个问题,可以把函数定义在全局,即从外部插入函数。

1 function sayName(){
2 console.log(this.name);
3 }
4 const Person = function(name,age){
5 this.name=name;
6 this.age=age;
7 this.sayName = sayName;
8 }
9 const p1 = new Person('Billy',21);

  这样便解决了相同逻辑的函数重复定义的问题,但是这样会污染全局命名空间,若这个对象需要多个方法,则需要在全局作用域定义大量函数,这样会严重污染全局作用域。因此使用原型模式便成为了唯一方法。

3、原型模式

  使用原型对象的好处是在上面定义的属性和方法可以被对象实例共享。代码如下:

1 function Person3(){
2 Person3.prototype.name='Billy';
3 Person3.prototype.age=21;
4 }
5 const p7 = new Person3;
6 const p8 = new Person3;
7 console.log(p7.name); //Billy
8 console.log(p7.name); //Billy

  绑定在构造函数上的属性实例都可以取到。这样便实现了属性共享,在构造函数中绑定函数也可以共享,这便解决了之前的所有问题。由此可见原型的重要性 :

  • 新创建的对象都有明显标识。
  • 可共享方法,且不会重复定义。
  • 不会污染全局命名空间。

javascriptRemke之原型的重要性的更多相关文章

  1. 深入理解JavaScript中创建对象模式的演变(原型)

    深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...

  2. 《JavaScript 闯关记》之原型及原型链

    原型链是一种机制,指的是 JavaScript 每个对象都有一个内置的 __proto__ 属性指向创建它的构造函数的 prototype(原型)属性.原型链的作用是为了实现对象的继承,要理解原型链, ...

  3. 何为JavaScript原型?读完你就明白了

    熟悉软件开发的朋友都知道,原型是产品或数据系统的一个基本的实用模型,通常为示范目的或开发程序的部份结构.原型的重要性不言而喻,接下来我就会为你讲解关于JavaScript中的原型概念.原型对象释义每一 ...

  4. 史上最全的Android开发学习教程集锦【初学者】

    根据Google的报告,截止2017年5月为止,Android活跃用户已超过20亿,并还在持续增长中.Android系统在几个主要的市场上已超过了iOS系统,特别是在美国,欧洲和日本,然而苹果确实在中 ...

  5. 深入理解javascript原型和闭包 (转)

    该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是和其他主流面向对象语言区别最大的两个部分--原型和闭包,当然,肯定少不了原型链和作用域链.帮 ...

  6. 深入理解javascript原型和闭包(完结)

    原文链接:http://www.cnblogs.com/wangfupeng1988/p/3977924.html 说明: 该教程绕开了javascript的一些基本的语法知识,直接讲解javascr ...

  7. 初涉JavaScript模式 (6) : 原型模式 【二】

    原型与in操作符 有两种方式使用in操作符:单独使用和在for-in循环中使用. 在单独使用时,in操作符会遍历实例公开(可枚举)的属性,如果找到该指定属性则返回true,无论该指定属性是存在与实例中 ...

  8. JS中面向对象的,对象理解、构造函数、原型、原型链

    6.1 理解对象 6.1.1 对象属性类型 ECMS属性有两种类型:数据属性和访问器属性 1 数据属性 [[configurable]] 表示能否通过Delete 删除属性从而从新定义属性,能否修改属 ...

  9. JavaScript之面向对象学习五(JS原生引用类型Array、Object、String等等)的原型对象介绍

    1.原型模式的重要性不仅仅体现在创建自定义类型方面,就连所有的原生的引用类型(Obejct.Array.String等等)都在构造函数的原型上定义方法和属性.如下代码可以证明: alert(typeo ...

随机推荐

  1. 删除mysql数据库后django重建数据库

    问题:由于表的结构设计的不太合理,后来要添加列,但是在django中使用makemigrations一直失败. 解决:索性就把mysql中对于django的数据库删了(其实也不用删除),在django ...

  2. TDSQL MySQL版基本原理-水平分表 读写分离 弹性扩展 强同步

    TDSQL MySQL版(TDSQL for MySQL)是部署在腾讯云上的一种支持自动水平拆分.Shared Nothing 架构的分布式数据库.TDSQL MySQL版 即业务获取的是完整的逻辑库 ...

  3. IMO 2021 第 1 题拓展问题的两个极值的编程求解

    IMO 2021 第 1 题拓展问题的两个极值的编程求解 本篇是 IMO 2021 第一题题解及相关拓展问题分析 的续篇. 拓展问题三: (I). 求 n 的最小值,使得 n, n + 1, ..., ...

  4. 【开发工具】Postman保姆级入门教程

    目录 一.简单使用 1. 创建命名空间 2. 创建新集合 3. 按模块整理接口 二.使用环境变量 1. 创建环境与环境变量 2. 使用环境变量 3. 登录后自动更新环境变量 转载请注明出处 一.简单使 ...

  5. 如何在RHEL7或CentOS 7系统下修改网卡名称(亲测有效~!)

    亲测有效的更改RHEL7或CentOS 7的网卡名称的方法, 按照以下4步来操作就可以实现! Step 1 :网卡配置文件名称重命名为eth0[root@localhost ~]# ifconfige ...

  6. mybatis动态sql以及分页

    1.mybatis动态sql 2.模糊查询 3.查询返回结果集的处理 4.分页查询 5.特殊字符处理 1.mybatis动态sql If.trim.foreach If 标签判断某一字段是否为空 &l ...

  7. VUE004. provide与inject的使用(祖先组件隔多层传静态值给子孙组件)

    provide和inject可以通过祖先组件隔三层四层甚至隔着九层妖塔传值给子孙组件. 需要注意的是这样的传值方式是非响应式的,需要结合自身的应用场景,比如将上传的限制条件通过父组件传值给子组件的子组 ...

  8. 常量&&变量

    一.常量:程序运行期间不变 常量使用: 二.八大基本数据类型变量: 其中,一个Byte类型数据占八个bit位,所以范围是(-2^7 ~ 2^7-1),数据最小的存储单位,是四分之一的int类型空间,所 ...

  9. java线程day-01

    综述:下面写的是我学习java线程时做的一些笔记和查阅的一些资料总结而成.大多以问答的形式出现. 一.什么是线程? 答:线程是一个轻量级的进程,现在操作系统中一个基本的调度单位,而且线程是彼此独立执行 ...

  10. 自己实现一个Controller——终极型

    经过前两篇的学习与实操,也大致掌握了一个k8s资源的Controller写法了,如有不熟,可回顾 自己实现一个Controller--标准型 自己实现一个Controller--精简型 但是目前也只能 ...