JS-建立对象

竖立对象

运用new Object()或许对象字面量都可以竖立对象,然则如许竖立的对象过于简朴,不易于对象的属性与要领的扩大与继续。
下面讲的对象可以与JavaEE中的bean做类比。

工场形式

对,起首可以想到的是运用设想形式中的工场形式

function createPizza(type) {
  var o = new Object();
  o.type = type;
  o.bake = function() {
    alert('Start~');
    alert(this.type);
    alert('End~');
  };
  return o;
}

var cheesePizza = createPizza('cheese');
var veggiePizza = createPizza('veggie');
cheesePizza.bake();

长处

工场形式处理了竖立多个相似对象的题目

瑕玷

对象没法辨认,即竖立出来的对象没法经由过程instanceof平分析出属于哪一种范例

组织函数形式

用组织函数可用来竖立特定范例的对象

// 组织函数首字母遵照OO言语通例举行大写
function Pizza(type) {
  this.type = type;
  this.bake = function() {
    alert('Start~');
    alert(this.type);
    alert('End~');
  };
}

var cheesePizza = new Pizza('cheese');
var veggiePizza = new Pizza('veggie');
cheesePizza.bake();

与工场形式比拟:

  1. 没有在要领中显现制造对象(o);
  2. 直接将属性与要领赋值给this;
  3. 没有return语句

在用new的时刻,会阅历一下4步:

  1. 竖立一个新对象
  2. 将组织函数的作用域赋值给新对象(此时this指向新对象)
  3. 实行组织函数代码(为对象增加属性)
  4. 返回新对象

假如不运用new,将组织函数当作函数运用,则this指向Global对象(在浏览器中为window对象),固然,可以运用call要领来指定作用域,比方

var o = new Object();
Pizza.call(o, 'salty');
o.bake();

运用组织函数要领,每一个实例对象都有一个constructor组织函数属性,该属性指向Pizza(运用对象字面量、工场形式要领竖立的对象该属性指向Object)

cheesePizza.constructor == Pizza

搜检某个对象属于哪一种范例,平常运用instanceof,cheesePizza同时属于PizzaObject(之所以属于Object,是由于一切对象均继续于Object)

cheesePizza instanceof Pizza;
cheesePizza instanceof Object;

长处

与工场形式比拟,组织函数形式可以辨认出对象范例
与下面的原型形式比拟,可以完成对象属性的相互自力,在援用范例属性上很有效

瑕玷

每一个实例对象的要领都是自力的,致使要领不可以同享

原型形式

每一个函数(不是实例对象)都有一个prototype属性,该属性是一个指针,指向一个对象,对象的用处是包括一切实例同享的属性和要领。prototype经由过程挪用组织函数竖立的谁人对象实例的原型对象。运用原型对象的优点是可以让一切实例对象同享属性与要领。

function Pizza() {

}

Pizza.prototype.type = 'original'
Pizza.prototype.bake = function() {
  alert('Start~');
  alert(this.type);
  alert('End~');
};

var cheesePizza = new Pizza();
cheesePizza.type = 'cheese';
var veggiePizza = new Pizza();
veggiePizza.type = 'veggie';

cheesePizza.bake();
veggiePizza.bake();

各个对象同享属性与要领,同时每一个对象都可以竖立本身的属性,并屏障掉原型对象的同名属性,由于同享属性与要领,所以以下等式建立

cheesePizza.bake == veggiePizza.bake

对象字面量重写原型对象

也可以经由过程对象字面量来重写全部原型对象:

Pizza.prototype = {
  type: 'original',
  bake: function() {
    alert('Start~');
    alert(this.type);
    alert('End~');
  }
}

如许完整重写,原型对象上的constructor属性不再指向Pizza函数(全新的constructor指向Object),不过不影响经由过程instanceof来辨认对象范例。假如constructor迥殊主要的话,可以显式将它置为恰当的值:

Pizza.prototype = {
  constructor: Pizza,
  type: 'original',
  bake: function() {
    alert('Start~');
    alert(this.type);
    alert('End~');
  }
}

不过这类体式格局会将constructor的属性特性变成可罗列,而默许情况下它是不可罗列的,假如想不可罗列,可以运用Object.defineProperty()要领。

原型的动态性

对原型对象的修正会体现在实例对象上,纵然实例对象先被竖立。然则经由过程对象字面量重写的原型对象则没有该动态性

长处

定义在原型对象上的属性,可以保证在各实例对象上的同享

瑕玷

关于援用范例的属性,各实例的同享会致使分外的题目。

组合运用组织函数形式与原型形式

整合组织函数形式与原型形式,组织函数形式用于定义实例属性,原型形式用于定义要领和同享属性。

动态原型形式

寄生组织函数形式

稳妥组织函数形式

各竖立形式在Chrome浏览器中的表现

可以经由过程Chrome浏览器视察运用工场形式竖立的cheesePizza对象属性为:

cheesePizza
{type: "cheese", bake: ƒ}
  bake: ƒ ()
  type: "cheese"
  __proto__:
    constructor: ƒ Object()
    hasOwnProperty: ƒ hasOwnProperty()
    isPrototypeOf: ƒ isPrototypeOf()
    propertyIsEnumerable: ƒ propertyIsEnumerable()
    toLocaleString: ƒ toLocaleString()
    toString: ƒ toString()
    valueOf: ƒ valueOf()
    __defineGetter__: ƒ __defineGetter__()
    __defineSetter__: ƒ __defineSetter__()
    __lookupGetter__: ƒ __lookupGetter__()
    __lookupSetter__: ƒ __lookupSetter__()
    get __proto__: ƒ __proto__()
    set __proto__: ƒ __proto__()

运用组织函数形式竖立cheesePizza对象属性为:

cheesePizza
Pizza {type: "cheese", bake: ƒ}
  bake: ƒ ()
  type: "cheese"
  __proto__:
    constructor: ƒ Pizza(type)
    __proto__:
      constructor: ƒ Object()
      hasOwnProperty: ƒ hasOwnProperty()
      isPrototypeOf: ƒ isPrototypeOf()
      propertyIsEnumerable: ƒ propertyIsEnumerable()
      toLocaleString: ƒ toLocaleString()
      toString: ƒ toString()
      valueOf: ƒ valueOf()
      __defineGetter__: ƒ __defineGetter__()
      __defineSetter__: ƒ __defineSetter__()
      __lookupGetter__: ƒ __lookupGetter__()
      __lookupSetter__: ƒ __lookupSetter__()
      get __proto__: ƒ __proto__()
      set __proto__: ƒ __proto__()

运用原型形式竖立cheesePizza对象属性为:

cheesePizza
Pizza {type: "cheese"}
  type: "cheese"
  __proto__:
    bake: ƒ ()
    type: "original"
    constructor: ƒ Pizza()
    __proto__:
      constructor: ƒ Object()
      hasOwnProperty: ƒ hasOwnProperty()
      isPrototypeOf: ƒ isPrototypeOf()
      propertyIsEnumerable: ƒ propertyIsEnumerable()
      toLocaleString: ƒ toLocaleString()
      toString: ƒ toString()
      valueOf: ƒ valueOf()
      __defineGetter__: ƒ __defineGetter__()
      __defineSetter__: ƒ __defineSetter__()
      __lookupGetter__: ƒ __lookupGetter__()
      __lookupSetter__: ƒ __lookupSetter__()
      get __proto__: ƒ __proto__()
      set __proto__: ƒ __proto__()

参考文章

ESLint 须要束缚 for-in (guard-for-in)

个人不定期更新主页

    原文作者:莫显辉
    原文地址: https://segmentfault.com/a/1190000017410621
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞