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. 学习PYTHON之路, DAY 5 - PYTHON 基础 5 (装饰器,字符格式化,递归,迭代器,生成器)

    ---恢复内容开始--- 一 装饰器 1 单层装饰器 def outer(func): def inner(): print('long') func() print('after') return ...

  2. JavaEE Log4j

    1.Log4j是Apache的一个开放源代码项目,可以通过一个配置文件来灵活的进行配置,而不需要修改应用的代码. 2.Log4j有三个主要部件组成: 记录器:按照布局中指定的格式把日志信息写入一个或多 ...

  3. NoSQl简介(转)

    NoSQL,全称是“Not Only Sql”,指的是非关系型的数据库.这类数据库主要有这些特点:非关系型的.分布式的.开源的.水平可扩展的.原始的目的是为了大规模web应用,这场全新的数据库革命运动 ...

  4. 2014中国黑客榜(beta版)

    黑客,英文hacker.精通计算机各类技术的计算机高手,泛指擅长IT技术的人群.计算机科学家. 最近受某机构所托搜集国内活跃黑客近况.本着客观专业,权威可信的原则参考了国内从00年到最新的黑客榜单,以 ...

  5. erlang服务器启动,有情况会报,enif_send: env==NULL no ono-SMP VMAborted 的错误报告?

    问题的原因所在: 1:因为你当前使用的主机是一个单核的主机(不会自动启动): 2:多核上如果不设置-smp enable是不会有什么问题的,因为从OTP R12B开始,如果操作系统报告有多于1个的CP ...

  6. Imagick 缩放图片和实现模糊

    Imagick功能相当的多,只是还不稳定,我下面的程序能够运行,但是会出现内存错误,但我们要的图片还是能够得到. 弄这个的原因是,一个客户要求在一个appcan的应用里面实现一个页面的背景图的缩放.调 ...

  7. 也说析构---C++

    正如我们知道的: 通过new分配到heap中的对象,当对其delete,才会被析构: 分配在stack中的对象,当其离开作用域时被析构:

  8. python网络编程【二】(使用TCP)

    1.建立socket 对于一个客户端程序来说,建立一个socket需要两个步骤.首先,您需要建立一个实际的socket对象.其次,您需要把它连接到远程服务器上. 在建立socket对象的时候,您需要告 ...

  9. .Net内置特性Attribute介绍

    特性Attribute概述 特性(Attribute)是一种特殊的类型,可以加载到程序集或者程序集的类型上,这些类型包括模块.类.接口.结构.构造函数.方法.字段等,加载了特性的类型称之为特性的目标. ...

  10. Nginx中的进程亲和性 affinity

    Nginx采用多进程Master/Worker结构,Worker进程数为CPU个数时工作效率最高,Nginx通过affinity为每个Worker进程绑定一个CPU,避免进程切换带来的消耗,同时能够保 ...