prototype

js 的对象比较

由于 js 是解释执行的语言, 那么再代码中出现函数与对象如果重复执行, 会创建多个副本

  1. 在代码中重复执行的代码容易出现重复的对象
  2. 创建一个 Person 构造函数, 以创建 对象. 要求有 name, age, gender 和 sayHello
  3. 代码出现的错误
     // 1
    function Person() {
    var o = {};
    o.name = ...
    return o;
    }
    // 2
    function Person () {
    name: ....
    age: ....
    ...
    }

  4. 传统的构造方法的定义方式会影响性能, 容易造成多个对象有多个方法副本. 应该讲方法单独抽取出来. 让所有的对象共享该方法.
  5. 可以考虑将方法全部放到外面但是有安全隐患
    • 在开发中会引入各种框架或库. 自定义的成员越多, 出现命名冲突的几率越大
    • 可能在开发中会有多个构造函数. 每一个构造函数应该有多个方法. 那么就会变得不容易维护.
  6. 任意一个对象都会默认的链接到它的原型中
    • 创建一个函数. 会附带的创建一个特殊的对象. 该对象使用 函数.prototype 引用. 称其为函数的原型属性.
    • 每一个由该函数作为构造函数创建的对象, 都会默认的连接到该对象上.
    • 在该对象访问某一个方法或属性的时候, 如果该对象中没有, 就会到这个神秘对象中去查找.

传统构造函数的问题

    function Foo() {
this.sayHello = function () {
}
}

  1. 由于对象是调用 new Foo() 所创建出来的. 因此每一个对象在创建的时候, 函数 sayHello 都会被创建一次
  2. 那么每一个对象都含有一个独立的, 不同的, 但是功能逻辑一样的函数. 比如: {} == {}
  3. 在代码中方法就会消耗性能. 最典型的资源就是内存.
  4. 这里最好的办法就是将函数体放在构造函数之外. 那么在构造函数中只需要引用该函数即可
     function sayHello () {}
    function Foo () {
    this.say = sayHello;
    }

  5. 会在开发中变得困难: 引入框架危险, 代码繁冗不好维护. 解决办法就是外面的函数如果不占用名字. 而且在函数旗下就好了.
  6. 每一个函数在定义的时候, 有一个神秘对象被创建出来.
  7. 每一个由构造函数创建的对象都会默认的连接到该神秘对象上.
     var f1 = new Foo();
    var f2 = new Foo();
    f1.sayHello(); // 如果 f1 没有 sayHello, 那么就会在 Foo.prototype 中去找
    f2.sayGoodBye(); // 如果 f2 没有改方法, 那么就会在 Foo.prototype 中去找

  8. 由构造函数创建出来的众多对象共享一个对象, 就是 构造函数.prototype
  9. 只需要将共享的东西, 重复会多占用内存的东西放到 构造函数.prototype 中, 那么所有的对象就可以共享了.

     function Foo() {}
    Foo.prototype.sayHello = function () {
    console.log( ... );
    };
    var f1 = new Foo();
    f1.sayHello();
    var f2 = new Foo();
    f2.sayHello(); f1.sayHello === f2.sayHello

  10. 练习: 写一个构造函数 Student, 要求有 name, age, gender, sayHello, study. 要求构造函数带参数.

常见错误

  1. 写 构造函数.prototype 的时候, 将属性也加到里面.

     function Person() {}
    Person.prototype.name = '张三';
    var p = new Person();

  2. 赋值的错误

     function Person() {}
    Person.prototype.name = '张三';
    var p1 = new Person();
    var p2 = new Person();
    p1.name = '李四'; console.log( p1.name );
    console.log( p2.name );
    // 如果是访问数据, 当前对象中如果没有该数据就到构造函数的原型属性中去找
    // 如果是写数据, 当对象中有该数据的时候, 就是修改值; 如果对象没有该数据, 那么就添加值

原型相关的概念

  1. 关于面向对象的概念

    • 类 class: 在 js 中就是构造函数

      • 在传统的面向对象语言中, 使用一个叫做类的东西定义模板. 然后使用模板创建对象.
      • 在构造方法中也具有类似的功能. 因此称其为类
        // 在 java 中, 最小的代码单位是 类
        class Program {
        // 成员
        }

    • 实例 ( instance ) 与对象 ( object )
      • 实例一般是指某一个构造函数创建出来的对象. 我们成为 xxx 构造函数的实例
      • 实例就是对象. 对象是一个泛称.
      • 实例与对象是一个近义词
    • 键值对与属性和方法
      • 在 js 中键值对的集合称为对象
      • 如果值为数据( 非函数 ), 就称该键值对为属性 property
      • 如果值为函数( 方法 ), 就称该键值对为方法 method
    • 父类与子类
      • 传统的面向对象语言中使用类来实现继承. 那么就有父类, 子类的概念
      • 父类又称为基类, 子类又称为派生类
      • 在 js 中常常称为父对象, 子对象. 基对象, 派生对象.
  2. 原型相关的概念
    • 神秘对象针对构造函数称为 "原型属性"

      • 神秘对象就是构造函数的原型属性
      • 简称原型
    • 神秘对象与构造函数所创建出来的对象也有一定关系
      • 关系是什么
      • 神秘对象针对构造函数创建出来的对象称为 "原型对象"
      • 简称原型
    • 对象继承自其原型
      • 构造函数创建的对象 继承自 构造函数的原型属性
      • 构造函数创建的对象 继承自 该对象的原型对象
      • 构造函数所创建出来的对象与构造函数的原型属性表示的对象是两个不同的对象
        • 原型中的成员, 可以直接被实例对象所使用
        • 也就是说实例对象直接 "含有" 原型中的成员
        • 因此 实例对象 继承自 原型
        • 这样的继承就是 "原型继承"
  3. 一些问题
    • {} 构造函数是什么?
    • 凡是字面量的对象都有构造函数
      • {} Object
      • [] Array
      • /./ RegExp
      • function ... Function

如何使用原型

为什么使用原型?

  1. 利用对象的动态特性

    • 构造函数.prototype.XXX = vvvv;
  2. 利用直接替换
     Student.prototype = {
    sayHello: function () {},
    study: function () {}
    };

Prototype之个人见解的更多相关文章

  1. 【笔记】js Array.prototype.slice.call(arguments) 将函数的参数转换为数组方法的见解

    我们知道函数里面的参数实际上是一个以数组形式储存的对象 但它并非一个数组 如果我们要将它转换为数组可以调用Array.prototype.slice() 这个方法 分析一下这个方法: Array.pr ...

  2. 对js原型对象、实例化对象及prototype属性的一些见解

    什么是原型对象? 请看下面的代码,我们以各种姿势,创建了几个方法! function fn1() { } var fn2 = function () { } var fn3 = new Functio ...

  3. C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝

    原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...

  4. React,关于redux的一点小见解

    最近项目做多页面应用使用到了,react + webpack + redux + antd去构建多页面的应用,本地开发用express去模拟服务端程序(个人觉得可以换成dva).所以在这里吐槽一下我自 ...

  5. 鄙人对constructor和prototype的总结

    在学习js面向对象过程中,我们总是对constructor和prototype充满疑惑,这两个概念是相当重要的,深入理解这两个概念对理解js的一些核心概念非常的重要.因此,在这里记录下鄙人见解,希望可 ...

  6. JS继承的一些见解

    JS继承的一些见解 js在es6之前的继承是五花八门的.而且要在项目中灵活运用面向对象写法也是有点别扭,更多的时候还是觉得面向过程的写法更为简单,效率也高.久而久之对js的继承每隔一段时间就会理解出现 ...

  7. javascript中数组化的一般见解

    javascript中数组化的一般见解,数组化浏览器中存在许多类数组对象,往往对类数组操作比较麻烦,没有数组那些非常方便的方法,在这种情况下,就有了数组化方法. 数组化的一般方法 1.第一种也是我们最 ...

  8. js闭包 和 prototype

    function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...

  9. PHP设计模式(六)原型模式(Prototype For PHP)

    原型设计模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型设计模式简单的来说,顾名思义, 不去创建新的对象进而保留原型的一种设计模式. 缺点:原型设计模式是的最主要的缺点就 ...

随机推荐

  1. 张艾迪(创始人): 整合全新的UIW.AD概念

    The World No.1 Girl :Eidyzhang The World No.1 Internet Girl :Eidyzhang AOOOiA.global Founder :Eidyzh ...

  2. socket:通常每个套接字地址(协议/网络地址/端口)只允许使用一次

    有两种解决方法,一种是加入try{}catch(){},程序就不会抱错了:一种是在设置好监听SOCKET后,将SOCKET的属性设置为可重复使用地址,如://创建监听SOCKET socketList ...

  3. C++语法-指针 (1)

    <C++程序设计> 谭浩强  清华大学出版社 2016-08-03 1.P167 一般的C++编译系统为每个指针变量分配4个字节的存储单元,用来存放变量的地址. 2.P169 .cpp文件 ...

  4. PHP发送电子邮件

    1.导入文件,如本案例把Stmp.class.php放到Common\Common目录下,代码很多,直接复制就行! <?php namespace Common\Common; class Sm ...

  5. EF中的Code First

     一些概念 Ÿ POCO POCO(Plain Old CLR Object)的概念是从java的POJO借用而来,而两者的含义是一致的,不同的仅仅是使用的语言不一样.所以POCO的解释就是“Plai ...

  6. 使用面向 iOS 的本机插件扩展 PhoneGap

    本文细致探讨了 Xcode(以 iOS 设备为目标)中的 PhoneGap(也称为 Apache Cordova)应用程序本机插件.如果您刚开始接触 PhoneGap 或者需要回顾 PhoneGap ...

  7. 将 Tor socks 转换成 http 代理

    你可以通过不同的 Tor 工具来使用 Tor 服务,如 Tor 浏览器.Foxyproxy 和其它东西,像 wget 和 aria2 这样的下载管理器不能直接使用 Tor socks 开始匿名下载,因 ...

  8. android开发 兵器

    spring for android andriod anotatons 按android原生的方式写代码,会导致冗余,代码丑陋,开发效率低下. 最近对项目代码进行一些梳理和改进.

  9. SQLserver 备份和还原 失败

    错误一: 备份对于服务器“xxxxxx”失败. System.Data.SqlClient.SqlError: 无法使用备份文件 'C:\Program Files\Microsoft SQL Ser ...

  10. Bootstrap学习笔记(二)

    这一节笔记主要记录排版内容笔记,其内容包括标题.文本(包括段落.粗斜体.对齐).列表.表格等. 一.标题 在bootstrap中H1-H6与非框架版的区别不大,需要注意的是<small>标 ...