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. synchronized和ReentrantLock

    一.什么是sychronized sychronized是java中最基本同步互斥的手段,可以修饰代码块,方法,类. 在修饰代码块的时候需要一个reference对象作为锁的对象. 在修饰方法的时候默 ...

  2. css利用padding生成图标

    先插入HTML结构: <div class="line-three"></div> <div class="circle"> ...

  3. Xcode模拟器不显示SDK版本,反而显示设备ID的解决办法

    今天在应用程序中修改了Xcode app 的名称,结果导致Xcode模拟器不显示SDK版本,反而显示设备ID了,感觉特别的忧伤......如图: 进到Xcode->window->Devi ...

  4. 基于注解的Spring AOP示例

    基于注解的Spring AOP示例 目录 在XML配置文件中开启 @AspectJ 支持 声明切面及切入点 声明通知 测试 结语 在XML配置文件中开启 @AspectJ 支持 要使用Spring的A ...

  5. Android之NDK开发(转)

    Android之NDK开发 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...

  6. H5之contenteditable

    场景: <div id='content' contenteditable='true' > hello </div> <button id='caret'>设置光 ...

  7. 【 2013 Multi-University Training Contest 8 】

    HDU 4678 Mine 对于每个空白区域,求SG值. 最后异或起来等于0,先手必败. #pragma comment(linker,"/STACK:102400000,102400000 ...

  8. 用java程序调用批处理文件

    用java程序执行批处理文件并打印出控制台信息: public class test { public static void main(String[] args) { try { //执行批处理文 ...

  9. JavaScript 闭包系列一

    一. 闭包的概念 闭包是有权访问另一个函数作用域中的变量的函数. 如下代码:根据变量作用域,函数outer中所有的局部变量对函数inner都是可见的.但是反过来不行,inner内部的局部变量对oute ...

  10. GridView获取列子段的几种途径

    GridView是ASP.NET中功能强大的数据显示控件,它的RowDataBound事件为我们提供了方便的控制行.列数据的途径. 要获取当前行的某个数据列,我在实践中总结有如下几种方法: 1. Ce ...