Javascript面向对象-对象属性详解

对象的属性指对象的成员。讲解属性之前介绍一下Object对象,Object对象是所有JavaScript对象的超类(基类)。本文将会使用到Object对象的一些方法。

一、对象的属性分类

我们先通过讲属性的一些分类,来明确一些概念

1. 属性可分为自有属性和继承属性

function Person(name,age){
  this.trueName=name;
  this.age=age;
}
Person.prototype.species='human';
Person.prototype.run=function () {
  console.log(this.trueName+' is running');
}
var p1=new Person('Lilyan',18);
console.log(p1);

对象中的属性,根据是否子属于自身的可分为自有属性和继承属性。
① 自有属性(own property) :也可叫实例属性;指对象自身的属性,上述的p1对象中的姓名、年龄等都是自有属性。
② 继承属性(inherited property):也可叫原型属性;指对象从原型中继承的属性。
我们通过在控制台输出p1来看一下:
在这里插入图片描述

2. 可分为属性和方法

上面的代码中run的属性是一个函数,当属性值是函数的时候,该属性被称为方法,可以说方法就是一种特殊的属性。

3. 可分为公有属性和私有属性

关于公有属性和私有属性,里面涉及到了很多名词,如私有属性、私有方法、公有属性、公有方法、特权方法,中间存在一些概念模糊的地方,,我的说法不一定是对的,但我个人就这样记忆了。
对于构造函数来说,构造函数的实例能够访问的属性和方法就是公有属性公有方法,定义在函数内部且没有通过this声明的属性和方法就是私有的属性和方法。

function Person(name,age) {
  this.name=name; //公有属性
  var _age=age; //私有属性,约定私有属性前加_
  //私有方法
  var checkAge=function(){
    return (_age<18)?_age:'保密';
  };
  //公有方法-特权方法
  this.introduce=function () {
    console.log(this.name+'的年龄:'+checkAge(_age));
  };
}
//公有方法
Person.prototype.species='人类';
Person.prototype.say=function () {
  console.log(this.name+'的年龄:'+this._age);
};
var p=new Person('张三',19);
console.log(p);
p.introduce();
p.say();

在这里插入图片描述
简单的说,打印实例时,能看到的就是公有属性公有方法,定义了又看不到的是私有属性/方法。
私有属性和私有方法只能在函数内部使用,所谓特权方法其实也是一种公有方法,它能够在构造函数外,被其实例调用,并且能够访问构造函数内的私有属性和方法(如果你了解执行上下文的知识,就很好理解)。
上面的例子中,公有方法say没有访问到私有属性,特权方法introduce访问到了私有属性和私有方法。

4.静态属性和静态方法

静态属性和静态方法一般指不需要构造函数的实例化,直接将构造函数作为对象,可以访问的属性和方法。

function Person(name) {
  this.name=name; //公有属性
}
Person.species='人类';
Person.say=function () {
  console.log(this.name+'的年龄:'+this._age);
};
console.log(new Person());
console.dir(Person);

在这里插入图片描述

二、属性的访问方式

  1. 可用为 ’ . '点访问方式:obj.propertyName,属性名称必须为一个字符串,不能为变量。
  2. 可用’ [ ] '中括号方法方式 ,obj[propertyName],此方法访问属性更加的灵活,可以使用变量来访问属性
    说明:访问一个不存在的属性,将返回undefined。给对象不存在的属性赋值,将会向该对象添加此属性。
    var p1={
      "true name":"Lily",
    }
    var tn="true name";          
    console.log(p1[tn]);           //Lily
    console.log(p1.gender);   //undefined
    p1.gender='female';		//新增属性
    console.log(p1.gender);     //female
    p1.gender='male';		//修改属性值
    console.log(p1.gender);  //male
    

三、新增/修改属性

上例中,通过给一个不存在的属性赋值的方法实际上实现了新增属性;
给一个已经存在的属性重新赋值,就实现了修改属性值。

四、删除属性 delete

说明:通过delete方法可以删除对象的自有属性

function Person(name,age){
  this.trueName=name;
  this.age=age;
}
Person.prototype.species='human';
Person.prototype.run=function () {
  console.log(this.trueName+' is running');
}
var p1=new Person('Lilyan',18);
delete p1.age;
delete p1['species'];  //species是p1的继承属性,静默失败

五、检测对象是否包含某个属性

  1. 使用in运算符判断对象是否包含某个属性(会检查自有属性和继承属性);
    语法:属性 in 对象
    返回值:如果存在,返回值为:true;不存在,则为:false。
    console.log('age' in p1);  //true,找到自由属性age
    console.log('constructor' in p1);   /true,在原型属性中找到constructor
    
  2. 判断对象是否拥有一个指定名称的自有属性
    语法:对象.hasOwnProperty(属性)
    返回值:如果存在,返回值为:true;不存在,则为:false。
    console.log(p1.hasOwnProperty('age'));  //true
    console.log(p1.hasOwnProperty('constructor'));  //false,不会检查原型
    
  3. 判断指定名称的属性是否为可枚举的自有属性
    语法:对象.propertyIsEnumerable(属性)
    前面的例子中,我们为p1增加了一个不可枚举的属性x
    console.log(p1.propertyIsEnumerable('age'));  //true
    console.log(p1.propertyIsEnumerable('x'));   //false
    

六、属性的遍历

这里用一个构造函数的例子,来讲解一下属性的遍历

function Person(name,age){
    this.trueName=name;
    this.age=age;
  }
  Person.prototype.species='human';
  Person.prototype.run=function () {
    console.log(this.trueName+' is running');
  }
  var p1=new Person('Lilyan',18);

  Object.defineProperty(p1,'x',{
    value:'x',
    enumerable:false
  });
  Object.defineProperty(Person.prototype,'y',{
    value:'y',
    enumerable:false
  });
  console.log(p1);  

在这里插入图片描述

  • for / in 语句 遍历对象可枚举自有属性和继承属性
  • Object对象的4个静态属性,Object.keys()、Object.values() 、Object.entries() 、Object.getOwnPropertyNames()可以实现对象的遍历
  1. Object.keys() 返回一个给定对象==可枚举的自有属性(键)==组成的数组
  2. Object.values() 返回一个给定对象可枚举的自有属性值组成的数组(ES6新增)
  3. Object.entries() 返回一个给定对象可枚举的自有属性键值对组成的数组(ES6新增)
  4. Object.getOwnPropertyNames() 返回一个给定对象对象不包括Symbol 属性全部的自有属性组成的数组。

上面的代码中,对象p1既有自有属性又有继承属性,其中还有不可枚举的属性x和y,下面就来遍历它

var forResult="for/in遍历结果(返回可枚举的自有属性和继承属性)";
  for(var key in p1){
    forResult+="\n"+key+":"+p1[key];
  }
  console.log(forResult);
  console.log("Object.getOwnPropertyNames()方法的遍历结果,返回全部的自有属性组成的数组(不包括Symbol属性):");
  console.log(Object.getOwnPropertyNames(p1));
  console.log("Object.keys()方法的遍历结果(返回可枚举的自有属性名组成的数组):");
  console.log(Object.keys(p1));
  console.log("Object.values()方法的遍历结果(返回可枚举的自有属性值组成的数组):");
  console.log(Object.values(p1));
  console.log("Object.entries()方法的遍历结果(返回可枚举的自有属性键值对组成的数组):");
  console.log(Object.entries(p1));

在这里插入图片描述

七、对象字面量与JSON

对象字面量与JSON 字符串形式上看起来很像,JSON 是一种独立的语言,JSON字符串现在常用于进行前后端的数据交互,JavaScript提供了一个内置对象JSON,可以实现js对象与json字符串的互转。

JSON 语法规则

  • 数据为 键/值 对。
  • 数据由逗号分隔。
  • 大括号保存对象
  • 方括号保存数组

JSON.stringify返回一个字符串,JS对象的可枚举自有属性成为json字符串的键,属性值成为键值;
方法名和方法会被过滤掉。
在这里插入图片描述
这个对象p1,转成JSON字符串

console.log(JSON.stringify(p1));  //{"trueName":"Lilyan","age":18}

PS:JavaScript的JSON对象

八 、属性描述符对象

在前面我们多次提到可枚举属性,不可枚举属性,其实能更加微观的角度去看属性,还可以有可写的属性,不可写的属性;可配置的属性不可配置的属性等等。
在ES5 中定义了一个名叫“属性描述符”的对象,用于描述对象属性的各种特征,属性的特征分为两种类型,数据属性访问器属性
也就是说我们给对象配置一个属性的同时,还可以配置这个属性的特征。
使用Object.getOwnPropertyDescriptor() 和Object.getOwnPropertyDescriptors() 可以返回指定对象属性的描述
在这里插入图片描述

  • 将数据属性理解为某属性作为数据表现出的特征,如属性值是多少、能不能被修改等等;
  • 访问器属性指某属性被读取或修改时表现出的特征。
  • 一个描述符不能同时有(value或writable)和(get或set)关键字(将会产生一个异常),如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。
  1. 数据属性包含的4个属性:
    数据属性默认值说明
    configrabletrue描述属性是否配置,以及可否删除
    enumerabletrue可枚举性描述属性是否会出现在for in 或者 Object.keys()的遍历中
    writabletrue可写性,表示能否修改属性的值。
    valueundefined数据属性,表示属性的值
  2. 访问器属性包含的4个属性:
    访问器属性默认值说明
    configrablefalse描述属性是否配置,以及可否删除
    enumerablefalse描述属性是否会出现在for in 或者 Object.keys()的遍历中
    getundefined当访问该属性时,该方法会被执行,没有参数传入,会传入this对象
    setundefined该方法将接受唯一参数,并将该参数的新值分配给该属性

使用for/in循环可以遍历对象的可枚举属性,下面我用Object对象的defineProperty方法为上面的p1对象增加一个不可枚举属性x

Object.defineProperty(p1,'x',{
  value:'x',
  enumerable:false
});
console.log(p1);  //Person {trueName: "Lilyan", age: 18, x: "x"}
console.log(Object.getOwnPropertyDescriptor(p1, 'x'));   //{value: "x", writable: false, enumerable: false, configurable: false}
for(var key in p1) {
  console.log(key);   //不会打印出x,x属性不可枚举
}

这里用到了Object对象的两个方法:

  1. Object.defineProperty(obj, propertyName, propertyDescriptor) :添加/修改对象指定属性的特性
  2. Object.getOwnPropertyDescriptor(object, propertyName) :返回对象属性的描述
    可以跳转到 JavaScript原生对象-Object对象详解
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值