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. VS2010 验证时出错。HRESULT = '8000000A'

    验证时出错.HRESULT = '8000000A' 在VS2010中,当为Windows窗体应用程序添加一个安装项目后,如果项目生成时出现以下错误: 验证时发生错误.HRESULT = '80000 ...

  2. javascript版快速排序和冒泡排序

    var sort = (function () { //快速排序 var quickSort = { partition: function (array, low, high) { if (low ...

  3. 实现远程FTP特定时间轨道号MODIS数据的搜索

    private ArrayList alst = new System.Collections.ArrayList();//建立ArrayList对象 int strLength = 0; strin ...

  4. android 使用httpclient访问网络

    在主活动类中,调用一个线程访问网络(android4.0以上耗时的操作不能放在主线程中):       //声明两个Button对象,与一个TextView对象private TextView mTe ...

  5. 深入浅出Mybatis系列(七)---mapper映射文件配置之insert、update、delete

    上篇文章<深入浅出Mybatis系列(六)---objectFactory.plugins.mappers简介与配置>简单地给mybatis的配置画上了一个句号.那么从本篇文章开始,将会介 ...

  6. js 读取 地址栏参数 转

    用JS获取地址栏参数的方法(超级简单) 方法一:采用正则表达式获取地址栏参数:( 强烈推荐,既实用又方便!)   function GetQueryString(name) {      var re ...

  7. PHP实现文件上传

    一.关于全局变量$_FILES $_FILES包含有所有上传的文件信息.假设文件上传字段的名称为 img.则 $_FILES['img']['name']:客户端上传的文件的原名称. $_FILES[ ...

  8. JS 跳转页面 在新的选项卡打开

    function going(url) { var a = $("<a href='" + url + "' target='_blank'>Apple< ...

  9. Shell练习

    1   在终端下运行程序,首先清屏,然后提示:“Input a file or directory name, please!”.从键盘输入一个字符串(如:xxx),如果该字符串是目录,则显示:“xx ...

  10. win8.1安装Matlab7.0的兼容问题

     Matlab7.0安装完成后打开就立即关闭,此时右键点击MATLAB7.0快捷方式-"用图形处理器运行"-"更改默认图形处理器",将"集成图形&qu ...