原型的概念以及为什么使用原型

原型

js 的对象比较

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

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

传统构造函数的问题

    function fuc() {
        this.sayHi = function () {
        }
    }
  1. 由于对象是调用 new fuc() 所创建出来的. 因此每一个对象在创建的时候, 函数 sayHi 都会被创建一次
  2. 那么每一个对象都含有一个独立的, 不同的, 但是功能逻辑一样的函数. 比如: {} == {}
  3. 在代码中方法就会消耗性能. 最典型的资源就是内存.
  4. 这里最好的办法就是将函数体放在构造函数之外. 那么在构造函数中只需要引用该函数即可
     function sayHi () {}
     function fuc () {
         this.say = sayHi;
     }
    
  5. 会在开发中变得困难: 引入框架危险, 代码繁冗不好维护. 解决办法就是外面的函数如果不占用名字. 而且在函数旗下就好了.
  6. 每一个函数在定义的时候, 有一个神秘对象被创建出来.
  7. 每一个由构造函数创建的对象都会默认的连接到该神秘对象上.
     var f1 = new fuc();
     var f2 = new fuc();
     f1.sayHi(); // 如果 f1 没有 sayHi, 那么就会在 fuc.prototype 中去找
     f2.sayGoodBye(); // 如果 f2 没有改方法, 那么就会在 fuc.prototype 中去找
    
  8. 由构造函数创建出来的众多对象共享一个对象, 就是 构造函数.prototype
  9. 只需要将共享的东西, 重复会多占用内存的东西放到 构造函数.prototype 中, 那么所有的对象就可以共享了.
     function fuc() {}
     fuc.prototype.sayHi = function () {
         console.log( ... );
     };
     var f1 = new fuc();
     f1.sayHi();
     var f2 = new fuc();
     f2.sayHi();
    
     f1.sayHi === f2.sayHi
    
  10. 举例: 写一个构造函数 Student, 要求有 name, age, gender, sayHi, study. 要求构造函数带参数.

常见错误

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

     function Student() {}
     Student.prototype.name = ‘胡歌‘;
     var p = new Student();
    
  2. 赋值的错误
     function Student() {}
     Student.prototype.name = ‘胡歌‘;
     var p1 = new Student();
     var p2 = new Student();
     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 () {}
     };
时间: 2024-07-30 20:30:21

原型的概念以及为什么使用原型的相关文章

javascript原型等概念

研究javascript的原型概念两天,看到这篇文章后,终于恍然大悟,里面的图展示了一切!大部分内容转载自:https://segmentfault.com/a/1190000005824449 一切皆为对象 殊不知,JavaScript的世界中的对象,追根溯源来自于一个 null 「一切皆为对象」,这句着实是一手好营销,易记,易上口,印象深刻. 万物初生时,一个null对象,凭空而生,接着Object.Function学着null的模样塑造了自己,并且它们彼此之间喜结连理,提供了prototy

面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式

什么是面向对象?面向对象是一种思想!(废话). 面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下来将为大家讲解在JS中面向对象的实现. 工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,而由于在ECMAScript中无法创建类,因此用函数封装以特定接口创建对象.其实现方法非常简单,也就是在函数内创建一个对象,给对象赋予属性及方法再将对象返回即可. function createBlog(

JavaScript 原型链学习(三)原型对象存在的问题 与 组合使用构造函数和原型

原型对象也不是没有缺点.首先,它省略了为构造函数传递初始化参数这一环节, 结果所有实例在默认情况下都将取得相同的属性值.虽然这会在某种程度上带来一些不方便, 但还不是原型对象的最大问题.原型对象的最大问题是由其共享的本性所导致的.原型中所有属性是被很多实例共享的,这种共享对于函数非常合适.对于那些包含基本值的属性倒也说得过去,毕竟(如前面的例子所示),通过在实例上添加个同名属性, 可以隐藏原型中的对应属性.然而,对于包含引用类型值的属性来说,问题就比较突出了.来看下面的例子. function

原型的概念

原型相关的概念 关于面向对象的概念 类 class: 在 js 中就是构造函数 在传统的面向对象语言中, 使用一个叫做类的东西定义模板. 然后使用模板创建对象. 在构造方法中也具有类似的功能. 因此称其为类 // 在 java 中, 最小的代码单位是 类 class Program { // 成员 } 实例 ( instance ) 与对象 ( object ) 实例一般是指某一个构造函数创建出来的对象. 我们成为 xxx 构造函数的实例 实例就是对象. 对象是一个泛称. 实例与对象是一个近义词

构造函数、实例和原型的概念和关系

每个函数都属于对象,都会有一个属性叫prototype.这个属性指向一个对象,我们把他叫做当前函数的原型对象.原型对象下面有个属性叫constructor.这个属性指向当前函数.函数又分为普通函数和构造函数.这里我们说一下构造函数.定义一个函数 : function Person(x, y ) {this.age = x;this.name = y;}var xiaoming= new Person(12, "xiaoming" ); 这里创建实例对象 xiaoming的时候就是调用了

js中原型的概念

原型链概念理解

参考:https://www.jianshu.com/p/72156bc03ac1: https://zhuanlan.zhihu.com/p/42963985: 原文地址:https://www.cnblogs.com/su20110702048/p/12505754.html

产品原型设计5:移动App原型设计神器 - POP(Prototyping on Paper)

一般来说,苦逼的互联网产品经理们都知道 Axure 这个原型设计工具,一方面是因为它提供了足够简单的拖拽操作,易上手,且有很多模板方便复用:另一方是因为它可直接输出html,直接在浏览器里给团队成员和老板展示原型,方便做可用性测试. 移动 App 越来越多,现在你不做一两款 App 出门简直都不好意思跟人打招呼了.不能直接上手 PS 的产品经理们,又在想怎样低成本地制作移动app原型了.Axure 和 OmniGraffle Pro 当然会被容易被想到,但通过这两个制作出来原型的要在手机上直接展

JS原型的动态性及实例与原型的关系

今天再读了<JS高程>的第六章,有了些深入的感悟和理解,总结分享一下. 创建对象的方式有很多,有一种是动态原型模式,最实用的是构造函数与原型组合的模式,原型的动态性在这两个模式里都有所体现,我本人的理解是:前者的“动态”是通过一些判断,看方法是否存在来决定是否对原型进行初始化,同时,在构造函数内部对原型的修改会立即体现在所有的实例中,后者的“动态”是主要是说无论是先创建实例还是先修改原型,对原型对象所做的修改都会立即反应在实例中,针对后者来个栗子(栗子1): function Person()