js面向对象浅谈(一)

弁言

关于面向对象,置信人人肯定不生疏。近来看了一些关于es6面向对象的学问,恰好经由过程这篇文章把关于面向对象的东西给串起来分享给人人。

什么是对象

许多人会蔑视我,说你这篇文章是骗骗刚入行的小朋友的吧,什么是对象我还能不晓得?骂我的吃瓜大众先岑寂一下,你能够对对象一窍不通。

{
    name: '李小花',
    sayname () {
        console.log(this.name)
    }
}

这是我们最罕见的对象,这个对象是经由过程对象字面量情势建立的。

对象的寄义是无序的鸠合,其属机能够包括基础值、对象或许函数。

属性范例

js中有两种内置的属性,数据属性和接见器属性,这两个属性是只要内部才接见的属性,所以这些属性都放在了两对方括号中,如[[enumerable]],人人在vue中常常

数据属性

数据属性包括一个数据值的位置。在这个位置能够读取和写入值。数据属性有 4 个形貌其行动的特征。
  • [[Configurable]]:示意可否经由过程 delete
    删除属性从而从新定义属性,可否修正属性的特征,或许可否把属性修正为接见器属性。

  • [[Enumerable]]:示意可否经由过程 for-in 轮回返回属性。

  • [[Writable]]:示意可否修正属性的值。

  • [[Value]]:包括这个属性的值。读取属性值的时刻,从这个位置读;写入属性值的时刻,把新值保留在这个位置。这个特征的默认值为
    undefined。

如今有一个对象经由过程字面量建立

     var person =  {
         name: '张全蛋'
     }
     

[[Configurable]]、[[Enumerable]]、[[Writable]]属性都会被设置为true,[[Value]]被设置为了‘张全蛋’。假如想修正这几个属性恣意一个值,必需运用赫赫有名的Object.defineProperty()要领,为啥说它赫赫有名,由于假如你打仗过vue,就晓得他核型就是经由过程这个要领完成的。

var person = {};

Object.defineProperty(person, 'name', {
    writable: false,
    value: '张全蛋'
})
Object {name: "张全蛋"}

《js面向对象浅谈(一)》

如今的name属性是只读的,假如是严厉形式的话,

《js面向对象浅谈(一)》

如许做还会报错。一样的也适用于其他属性,我这里就不逐一演示了。

注重⚠️,Object.defineProperty()要领只要当代浏览器才支撑,IE8只是部份完成。

接见器属性

接见器属性不包括数据值,它们包括一对 getter 和 setter 函数(这两个函数都不是必需的)。在读取接见器属性时,会挪用
getter 函数,这个函数担任返回有用的值;在写入接见器属性时,会挪用 setter
并传入新值,这个函数担任决议怎样处置惩罚数据。接见器属性有以下 4 个特征。

  • [[Configurable]]:示意可否经由过程 delete 删除属性从而从新定义属性,可否修正属性的特征,或许可否把属性修正为数据属性。

  • [[Enumerable]]:示意可否经由过程 for-in 轮回返回属性。

  • [[Get]]:在读取属性时挪用的函数。默认值为 undefined。

  • [[Set]]:在写入属性时挪用的函数。默认值为 undefined。

接见只能经由过程bject.defineProperty()要领来定义。

var book = {
  _year: 2004,
  edition: 1
};

Object.defineProperty(book, 'year', {
  get: function() {
    return this._year;
  },
  set: function(newValue) {
    if (newValue > 2004) {
      this._year = newValue;
      this.edition += newValue - 2004;
    }
  }
});

book.year = 2005;
alert(book.edition);  // 2
alert(book.year); // 2005

接见器属性 year 则包括一个 getter 函数和一个 setter 函数。getter 函数返回 _year 的值,setter 函数经由过程计算来肯定准确的版本。因而,把 year 属性修正为 2005 会致使 _year 变成 2005,而 edition 变成 2。这是运用接见器属性的罕见体式格局,即设置一个属性的值会致使其他属性发生变化。

注重⚠️,接见器属性只要IE9以上才支撑,这就是为何VUE只能支撑到IE9的缘由。

建立对象

js面向对象第一步是什么?答:建立对象。建立对象有许多中体式格局,我们最经常使用的是对象字面量来建立对象,var obj = {},你看我这不就建立了一个对象了吗,我还干吗要继续相识那些奇葩的要领呢?这么想的人该死只身,多控制些找对象只要长处没有害处哈。正派的,高阶上有这么一句话,运用对象字面量建立单个对象,有个显著的瑕玷,运用同一个接口建立许多对象,会发生大批反复的代码。为相识决这个题目,我们须要相识下面?这些体式格局。

工场形式

工场形式很简单,贴上一段代码。

function createPerson (name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function () {
        alert(this.name)
    }
    return o;
}
var person1 = createPerson("铁蛋", 20, '领班')

var person2 = createPerson("李四", 30, '挖掘机驾驶员')

工场形式的长处没必要多说,假如我想建立两个对象,上面一样有name、age、job属性,如许就省去了建立包括一样属性多个对象的贫苦,然则却没有处理对象辨认的题目。
有人会问,对象辨认是什么鬼。我们建立对象是为了模拟类的观点,这里的person1,person2应当都属于“人”一类,然则明显我们如今没办法将他们归为一类,所以这个时刻逼格更高的要领涌现了。

组织函数形式

 function Person (name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
        alert(this.name)
    }
}
var person1 = new Person("铁蛋", 20, '领班')
var person2 = new Person("李四", 30, '挖掘机驾驶员')

这里有个明显很凸起的处所,就是这个Person的P是大写的,实在大写不是必需的,听说这类习气是许多后端程序员转前端带过来的。组织函数形式跟工场形式不一样的处所还在于,没有用new Object显式地建立对象,一样没有return语句。
那我们在new完一个组织函数,实则发生一个实例,我们new一个组织函数,会阅历以下奇异的四步。

建立对象 将this指向这个新对象 为这个对象增加属性 返回这个对象

person1、person2 是我们经由过程 new Person这个组织函数获得的,所以这两个的组织函数都是Person,constructor(组织函数)属性就都是Person,我之前一向都不能明白constructor是什么东西,如今才明白本来constructor的中文翻译就是组织函数?,也难怪我英文最熟的一句就是”hello kugou”了。我们能够经由过程运用instanceof操纵符来检测对象的范例。

 let arr = new Array(2)
 arr instanceof Array  // true
 arr instanceof Object // true

组织函数优于工场形式也是在于它能够经由过程instanceof辨识出一类的对象。

接下来人人看一段平常没品的面试官会考的题目

this.name = "张全蛋"
function Person (name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
        alert(this.name)
    }
}
var person1 = new Person("铁蛋", 20, '领班')
var person2 = Person("李小花", 30, "厂花")

person1.sayName()  // 铁蛋
person2.sayName() // 报错

我们首先要肯定一个观点,组织函数也是函数,假如不必new 的体式格局来挪用它,它跟一般函数没有半毛钱的区分,我们晓得在函数的作用域是window,所以this指向的是window,所以这段代码person2对象this就是window,window没有sayName属性,所以会报错。假如经由过程的是new体式格局挪用的话,我们上面也讲了,为将this赋值给这个对象,所以this就是person1这个实例。那末组织函数是否是没有瑕玷呢?明显是不对的,由于我已这么问了。组织函数的瑕玷,每一个要领都要在实例上从新建立一遍,js中函数也是对象,定义函数就是实例化对象

function Person (name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = new Function () {
        alert(this.name)
    }
}

每次new一个function就会多一次标识符剖析,标识符(通常指定名)的剖析是有价值的,实际上没有那种计算机操纵能够不发生机能开支。在实行环境的作用域链(扯到作用域链就肯定会扯到闭包题目,今后有空再细致聊聊闭包)中,一个标识符地点的位置越深,它的读写速率也就越慢。也就是说函数中读写局部变量老是最快的,而读写全局变量老是最慢的。由于全局变量老是在实行环境作用域的末尾。实在我们能够将函数移出来当全局函数来处置惩罚,但那样会形成全局函数污染,这里就不多做引见。

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