JavaScript基本进修——面向对象部份(属性范例)

媒介

JavaScript发明之始,从技术上来说就是一门面向对象的言语,但在ES6之前,JS的许多特性和传统的面向对象言语有所差别,比方没有类的观点(ES6有了class)。本日连系《JS高编》第六章最早回忆和深切进修面向对象部份,包括对象、原型、原型链、继续等部份。

一、明白对象

谈JS的对象之前,先温习一下面向对象的基本观点和特性吧。
面向对象OOP(Object-oriented programming),连系维基百科和百度百科的论述,再谈谈我的明白。

官方诠释:
面向对象就是基于对象观点,以对象为中间,以类和继续为组织机制,来熟悉、明白、描写客观天下和设想、构建响应的软件体系

我的明白:
在JavaScript的天下中,万物皆对象。任何事和物你都可以将其定义为一个对象,程序员界有个笑话就是只身狗可以new一个对象嘛……我的深刻明白,假如我是一个天主,这个天下的任何人和事相对于我而言都是一个对象。有了掌握对象的权利,我就可以对他们举行任何操纵。针对事,我可以宣布一个命令,宣布一个政策,通知他人怎样实行,什么时刻最早,什么时刻完毕。针对人,我可以把他们分为男子、女人,这就是类。然后我可以限定他们的儿子是男子照样女人,是男子那就必须有和爸爸一样的性别特性,这就是继续。我还可以掌握他们什么时间做什么事等等,全部历程我都是缭绕某个对象来睁开的,那末这个历程叫做面向对象。

特性:
1.类
2.继续
3.封装
4.多态
详细的在背面进修和温习时再谈。

二、对象的属性范例

let obj = {
    name:"勾鑫宇",
    age:23
}

1.数据属性:[[Configurable]],[[Enumerable]],[[Writable]],[[Value]]
2.接见器属性:[[Configurable]],[[Enumerable]],[[Get]],[[Set]]

书上讲到属性范例时,只是简朴提了一下是为了示意对象的特性,形貌了属性的特性,并且在JS中不能直接接见。光看引见不太明白究竟是干什么的,然则看了数据属性的内容以后,发明不难明白。

我的明白,数据属性就是我们可以从泉源去掌握一个对象的属性是不是能被修正、删除、轮回等,并可以经由过程接见器属性在他人不晓得的状况下举行数据处理。经由过程Object.defineProperty()这个要领,我们可以去设置这些限定对象属性操纵的值,从而限定他人对某个对象属性的操纵。举个例子,上面的obj这个对象的name属性的值是“勾鑫宇”,从现在起我不想任何人可以修正它的值,那末我就经由过程数据属性来将这个属性设置为不可修正,他人用obj.name = "张三"来修正就不会见效了。而我假如想在修正name属性的值后同时让age也随着转变,那末此时就可以用接见器属性来举行数据处理。

我们是经由过程Object.defineProperty()这个要领来举行两种属性的设置。那末起首相识一下Object.defineProperty()这个要领,它吸收三个参数:

Object.defineProperty(对象名,属性名,形貌符对象)
//举例
Object.defineProperty(obj,"name",{
    writable:false,//设置不可修正
    enumerable:false//设置不可轮回到该属性
})

可以在对象的constructor中找到该要领
《JavaScript基本进修——面向对象部份(属性范例)》

同时,我们可以经由过程Object.getOwnPropertyDescriptor()要领来检察这四个特性的设置状况。接收两个参数:

Object.getOwnPropertyDescriptor(对象名,属性名)

数据属性

数据属性包括一个数据值的位置。在这个位置可以读取和写入值,有4个形貌其行动的特性。

下面就详细来对每一个数据属性举行剖析:
1.[[Writable]]:英文意义译为“可写的”,可明白为“可修正的”。这个属性用来设置对象的某个属性是不是能被修正,默以为true。

//举例
let obj = {
    name:"勾鑫宇",
    age:23
}

Object.defineProperty(obj,"name",{
    writable:false,//设置不可修正
})

//这时刻再举行修正就不会见效,严厉情势下会报错
obj.name = "张三"
console.log(obj.name)//输出的照样勾鑫宇

严厉情势报错

《JavaScript基本进修——面向对象部份(属性范例)》

2.[[Enumerable]]:英文译为“可数的,可罗列的”,是不是支撑for-in轮回来返回属性,默以为true。

//举例
let obj = {
    name:"勾鑫宇",
    age:23,
    gender:male
}

Object.defineProperty(obj,"name",{
    enumerable:false,//设置不可经由过程for-in轮回返回
})

//轮回测试
for(let i in obj){
  console.log(i)//输出结果为age,gender,没有name属性,结果就像隐蔽了这个属性。
}

//但这时刻我们的name属性照样存在的
console.log(obj)

3.[[value]]:这个就不说翻译了,人人都晓得,就是值。这个特性是设置我们对象某个属性的值,读值、写值都在这里,默认值为undefined。

//举例
let obj = {
    name:"勾鑫宇",
    age:23,
    gender:male
}

Object.defineProperty(obj,"name",{
    value:"张三",//设置name的值为张三
})

console.log(obj.name)//输出为张三

//设置value不影响背面再次修正值,value相当于修正了一次你最早定义的值罢了。
obj.name = "傻逼"
concole.log(obj.name)//输出为“傻逼”

4.[[Configurable]]:英文译为“可设置的”,这个和前面的Writable有什么区分呢?放到末了讲是有缘由的。前面有设置修正,设置轮回,设置值,然则还没有设置是不是可删除。Configurable就是做这个事变的。它示意可否经由过程delete删除属性从而从新定义属性,默认值为true。

//举例
let obj = {
    name:"勾鑫宇",
    age:23,
    gender:male
}

Object.defineProperty(obj,"name",{
    configurable:false,//不允许删除属性
})

delete obj.name//报错"Uncaught TypeError: Cannot delete property 'name' of #<Object>"

这个属性另有最主要的一个特性,就是当你设置为false事后,就不能再设为true了,纵然你设置了也无效。书上说得个时刻你再设置value,enumerable都不会见效,只能设置writable,那末我们来尝尝。

//接着上面再把configurable修正为true
Object.defineProperty(obj,"name",{
    configurable:true,
})
//此时为会报错“Uncaught TypeError: Cannot redefine property: name”

//接着再次挪用
Object.defineProperty(obj,"name",{
    value:'张三'
})

console.log(obj)//此时打印出来的是“张三”,而并书上所说的不能修正value的值。

//设置enumerable
Object.defineProperty(obj,"name",{
    enumerable:false//报错"Uncaught TypeError: Cannot redefine property: name"
})

测试了许多遍,value值在configurable为false的状况下仍然是可以修正的。

//设置writable
Object.defineProperty(obj,"name",{
    writable:false//不会报错
})

//再次修正writable
Object.defineProperty(obj,"name",{
    writable:true//报错“Uncaught TypeError: Cannot redefine property: name”
})

//修正value
Object.defineProperty(obj,"name",{
    value:"张三"//报错“Uncaught TypeError: Cannot redefine property: name”
})

上面设置writable申明在configurable和writable同时为false的状况下,就不能再修正任何值了。
Configurable还能掌握是不是能修正为接见器属性,这个在接见器属性的时刻再讲。

接见器属性

接见器属性不包括数据值,包括一对getter和setter函数,读取接见器属性时挪用getter,写入时挪用setter,并负责处理数据。
接见器属性一样有4个特性值可以设置:

1.[[Configurable]]:和数据属性的功用一样,只是有一点区分就是可否修正为数据属性。
2.[[Enumerable]]:和数据属性的功用一样。
3.[[Get]]:读取属性时挪用,默认值为undefined。
get函数就是可以让你读取对象中的某个属性,条件是这个属性自身是只能经由过程对象要领来接见的,也就是说定义时要有下划线暗号,不然自身就可以直接接见的话,用get也没有意义了。

//举例
let obj = {
    _name:"勾鑫宇",//下划线是一种暗号,示意只能经由过程对象要领接见
    age:23,
    gender:male
}

console.log(obj.name)//输出为undefined

//用get要领来读取这个属性,并返回给对象
Object.defineProperty(obj,"name",{
    get(){
      return this._name
    }
})

console.log(obj.name)//输出“勾鑫宇”

4.[[Set]]:set函数就是写入属性的时刻挪用,默认值为undefined。
set函数会吸收一个参数,这个参数就是我们修正对象或增加对象的属性值。

//举例
let obj = {
    _name:"勾鑫宇",
    age:23,
    gender:male
}

//用set要领来写入这个属性
Object.defineProperty(obj,"name",{
    set(val){
      this._name = 'hh'+val
    }
})
obj.name = "张三"
console.log(obj.name)//输出为undefined

这个时刻我们就没法举行下去了,由于无论怎样,都是输出undefined。缘由就是由于我们没有运用get函数去读取我们写入的属性值,记着name在初始定义时就必须是_name

//同时运用get和set
let obj = {
    _name:"勾鑫宇",
    age:23,
    gender:male
}

//用set要领来写入这个属性
Object.defineProperty(obj,"name",{
    get(){
      return this._name
    },
    set(val){
      this. = 'hh'+val
    }
})
obj.name = "张三"
console.log(obj.name)//输出'hh张三'

从上面的代码就可以看出这个set和get函数的壮大的地方,那就是可以举行数据处理。我们可以经由过程set函数来举行对象里差别属性的关联,也可以完成属性值的种种盘算。

//举例
let obj = {
    _name:"勾鑫宇",
    age:23,
    gender:male
}

//用set要领来举行差别属性间的关联
Object.defineProperty(obj,"name",{
    get(){
      return this._name
    },
    set(val){
      if(val === '张三'){
        this._name = val;
        this.age = 18
      }
    }
})

//修正属性值
obj.name = '张三';
console.log(obj)//输出 {name:'张三',age:18,gender:male}

除了Object.defineProperty()要领,另有Object.defineProperties()要领,望文生义,复数情势就是可以同时定义多个属性。它接收两个参数:

Object.defineProperties(obj,{
  name:{
    writable:false
  },
  age:{
    configurable:true
  }
  ...
})

这就是对属性范例的一个进修和明白,若有毛病,请用力点我。

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