js 原型理解(原型对象)

  以前在网上搜了一些关于js原型的资料,看了过后,是有一部分理解,但是还不够全面,在这我就写写下关于js的原型。

  看了下js高级程序设计,我对js原型的有了一定的理解。里面谈到我们创建对象时,如果一直手写一些相似的对象或者说里面有重复的属性时,会非常麻烦。列如:

  

let a = {
      name: ‘a‘,
      idnex: 1
    }
let b = {
      name: ‘b‘,
      idnex: 2
    }

  为了解决这种问题,就出来了一些能创建对象的模式。

//工厂模式

function createObj (name, index) {
      let o = {}
      o.name = name
      o.index = index    o.sayName = function () {      alert(this.name)    }
      return o
 }
let a = createObj(‘a‘, 1)
let b = createObj(‘b‘, 2)

  这种模式,虽然解决创建多个相似对象的问题, 但却没有解决对象识别的问题(即怎样知道一个对象的类型)。对于这句话,我的理解是,这样创建的对象,在类型上区别不出来吧,这种模式产生的对象,感觉都是同一层面上的,都是通过 new Object 出来的(而原型是可以通过new CreateObj  等构造名创建)

  随着js发展,构造函数模式就出来了

  //构造函数模式

  function CreateObj (name, index) {
      this.name = name
      this.index = index
      this.sayName = function () {
        alert(this.name)
      }
    }
    let a = new CreateObj(‘a‘, 1)
    let a = new CreateObj(‘b‘, 2)

  这种模式的问题就是每个方法都在实例上创建一遍,如上面的sayName.

  我们可以把方法提取出来:

  

  function CreateObj (name, index) {
      this.name = name
      this.index = index
      this.sayName = sayName
    }
     function sayName () {
        alert(this.name)
      }
    let a = new CreateObj(‘a‘, 1)
    let a = new CreateObj(‘b‘, 2)

  这样的话,所有的实例都会共有这个sayName方法。但是也有新的问题,这样定义的方法是全局的,如果定义多个方法,命名都会要让人崩溃的,也会造成覆盖的风险。

对以上的这些问题,就可以用原型来解决。

  //原型模式    

   function A () {
    }
    A.prototype.name = ‘a‘
    A.prototype.index = 1
    A.prototype.syaName = function () {
      console.log(this.name)
    }                              //原型对象:{name: a, index: 1, syaName: function () {console.log(this.name) } }
   let a1 = new A()
    let a2 = new A()

  这里用了prototyope(原型,js仅仅会在函数给它这个属性),这里 A.prototype是指向一个对象的,你就当它就是一个原型对象。上面创建了一个原型对象且包含属性name、index、sayName,然后通过它new出来的实例,本身会有一个[[prototype]]属性,在js中这是个内部属性,一般不能直接访问,但是在Firefox、Safari、Chrome在每个对象上都支持一个属性_proto_,这个可以理解成这个内部属性。 [[prototype]]这个属性指向的就是它的原型对象,但是这里要注意的是,在原型机制中,只会访问实例本身没有的属性,才会再去找原型对象中是否有这个属性,如:

  

  function A () {
  }
  A.prototype.name = ‘a‘
  A.prototype.index = 1
  A.prototype.syaName = function () {
    console.log(this.name)
  } 

  A.prototype.c = [1, 34]
  let a1 = new A()
  let a2 = new A()
  console.log(a1.a) // 1
  console.log(a2.a) // 1
  console.log(a2.c) // [1, 34]
  console.log(a2.c) // [1, 34]
  a2.a = 2
  a2.c.push(‘3‘)
  console.log(a1.a) // 1
  console.log(a2.a) // 2
  console.log(a2.c) // [1, 34, 3]
  console.log(a2.c) // [1, 34, 3]

  这里可能有人会疑惑,为什么a1中的a不会改变,c改变了。先说下整个过程:

  a1、a2都没有属性a,c ,所以它就去访问它的原型对象,如果都是只是访问的话,因为访问的是同一个对象,所以就得到同样的值。

  然后, a2.a  =  2  这个赋值操作,是会优先对a2这个对象进行赋a这个属性的(那么a2就会有自己的属性a并且值为2),而不是去对原型对象的属性a重新赋值。而a2.c不是赋值操作,只是对元数据进行修改,因为a2里面没有c属性,也修改不了自己的属性c,那么就会对原型对象里面的数据进行修改了。我们可以验证一下:

  a2.a = 2
  a2.c = [1, 2]
  console.log(a1.a) // 1
  console.log(a2.a) // 2
  console.log(a2.c) // [1, 34]
  console.log(a2.c) // [1, 2]

  这里都是给自己的实例对象添加了各自的属性,而原型对象并没有改变,所以他们自己有的属性就访问自己的,没有的就访问没改变的原型对象。

  简而言之,js中每个对象会有一个内部属性[[prototype]],该属性指向它的原型对象。

       而原型对象,可以通过函数的prototype来创建以及给它赋属性。

       每个通过原型构造函数产生的实例对象,是共享同一个原型对象的,该对象的属性值是不能通过实例赋值修改的。

 

时间: 2024-10-07 19:54:07

js 原型理解(原型对象)的相关文章

node.js javascript理解原型继承

util.inherits util.inherits(constructor, superConstructor)是一个实现对象间原型继承的函数. JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同.JavaScript 没有提供对象继承的语言级别特性,而是通过原型复制来实现的 var util = require('util'); function Base() { this.name = 'base'; this.base = 1991; this.sayHello =

1--面试总结-js深入理解,对象,原型链,构造函数,执行上下文堆栈,执行上下文,变量对象,活动对象,作用域链,闭包,This

参考一手资料:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/中文翻译版本:https://zhuanlan.zhihu.com/p/32042645 Javascript 是一种单线程编程语言,这意味着它只有一个调用栈,call Stack(调用栈 ,,先入后出) 核心:对象,原型链,构造函数,执行上下文堆栈,执行上下文,变量对象,活动对象,作用域链,闭包,This js原型链? 定义 原型对象也是简单的对象并且可以拥有它们自

JS中面向对象的,对象理解、构造函数、原型、原型链

6.1 理解对象 6.1.1 对象属性类型 ECMS属性有两种类型:数据属性和访问器属性 1 数据属性 [[configurable]] 表示能否通过Delete 删除属性从而从新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性.对象上定义的属性默认值为true [[enumerable]] 表示能否通过for-in循环返回属性.直接在对象上定义的属性,它们的这个特性默认值为true [[writable]] 表示能否修改属性值.像前面例子中那样直接在对象上定义的属性,它们默认值为t

理解js的prototype原型对象

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法.如果按照字面意思来理解,那么prototype就是通过调用构造函数而创建的那个对象实例的原型对象.使用原受对象的好处是可以让所有对象实例共享它所包含的属性和方法.换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中,如下面的例子所示. function Person(){} Person.prototype.n

js中原型和原型链理解

js中属性的继承以及查找都会用到原型链的知识,对于深入学习js的人来说是一个难点也是一个重点,下面梳理下对于原型以及原型链的理解. 首先,我们要知道什么是原型以及原型链?他们有什么样的作用? 可以理解为JS对象在创建时都会与之关联另一个对象,这就是我们所说的原型,每一个对象都会从原型"继承"属性.下图表示了构造函数与实例原型的关系,其中Object.prototype表示实例原型. 那么实例与实例原型又是怎么联系的呢?接下来又要说到另一个属性__proto__,每一个JS对象都有一个属

理解原型对象

理解原型对象: 创建函数的时候,会为该函数创建一个prototype属性,这个属性指向函数的原型对象.默认情况下所有的原型对象都会获得一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针. 自己的理解,函数是一个对象 ,原型对象也是一个对象,我们在创建函数的时候就会自动为该函数创建一个原型对象,这两个对象怎么关联呢,在创建函数的时候默认就为函数创建了一个属性prototype(其实是指针)这个属性指向原型对象.那么这样函数就和他的原型对象关联起来了.那么这是函

理解javascript 对象,原型对象、闭包

javascript作为一个面向对象的语言,理解 对象.原型.闭包.模块模式等技术点对于成为一名合格的javascript程序员相当重要,多年没写过blog,今天就先拋个玉,在下基本也不做前端,但颇感兴趣,愿意和大家一起学习.此篇只是对自己认为的比较重要的知识点进行了说明,连贯性不是特别好,大家共同进步. 注意:文中中文并非英文翻译,只是个人理解. 理解面向对象 对象(object) An object is a collection of properties and has a single

js原型和原型链个人理解(我的理解)

<script> //普通对象与函数对象,js万物皆是对象 //自带的 function a1() { function f1() {} var f2=function () {} var f3=new Function('str','console.log(str)'); var o3=new f1(); var ol={}; var o2=new Object(); console.log(typeof Object);//function console.log(typeof Funct

【JS】JavaScript中对象的创建与原型模式

 ECMAScript中没有类的概念,因此它的对象与基于类的语言中的对象有所不同. 1.理解对象 创建对象最简单的方式是创建一个Object实例,再为它添加属性和方法,如下: <span style="font-family:SimSun;font-size:12px;">var people = new Object(); people.age = 20; people.sayAge = function(){ alert(this.age); };</span

JS原型、原型链深入理解

原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性. 一.初识原型在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个”[[Prototype]]”内部属性,这个属性所对应的就是该对象的原型.“[[Prototype]]”作为对象的内部属性,是不能被直接访问的.所以为了方便查看一个对象的原型,Fir