js 属性的那些事

js中一切皆对象,而对象,本质上是一系列属性的集合.

对象的属性可分为:

命名属性 : 可直接通过“.”访问到的属性
数据属性 : 专门保存一个值的属性
访问器属性 : 保护数据属性的特殊属性
内部属性 : 不能通过“.”直接访问的属性 (比如 : class proto

属性的Descriptor 四大特性:

getOwnPropertyDescriptor 查看属性四大特性

var person ={name:'Tom'};
console.log(Object.getOwnPropertyDescriptor(person,'name'));
// { value: 'Tom',
//   writable: true,
//   enumerable: true,
//   configurable: true }

非defineProperty定义的属性,四大特性默认值都是true

  • writable ?—— ?是否为可写
  • enumerable ?—— ?是否为可枚举,
  • configurable ?—— ?是否为可配置的,false即不能再配置熟悉的特性,不可删除.

怎么设置属性的特性呢? defineProperty

另一个版本,一次定义多个属性 defineProperties

Object.defineProperty(person,'id',{
    value:1717
});
console.log(Object.getOwnPropertyDescriptor(person,'id'));
// { value: undefined,
//     writable: false,
//     enumerable: false,
//     configurable: false }

可见:defineProperty定义的属性,四大特性默认值都是false. 非defineProperty定义的属性,四大特性默认值都是true
下面看看这个特殊的属性:

person.id =199; // writable: false 不可写
console.log(person.id); //1717 没变 'strict'下直接报错

既然不可写,先通过defineProperty 把它变为可写

Object.defineProperty(person,'id',{
    writable:true
});

忘记configurable: false 了吗,报错 TypeError: Cannot redefine property: id
不可逆的设置,重来:

Object.defineProperty(person,'id',{
    value:1717,
    writable:true,
    configurable:true,
    enumerable:false
});

好了,现在的person可写 可重新配置 就是不可枚举,for in 枚举不到id属性

for(let k in person){
    console.log(k);
}  //name

那么, 不可枚举的属性怎么才能访问呢? ‘.‘访问和getOwnPropertyNames

console.log(person.id) // 1717
console.log(Object.keys(person)); //[ 'name' ] 顺便混进来
console.log(Object.getOwnPropertyNames(person)); //[ 'name', 'id' ]

访问器属性

访问器属性也是一种属性,他具有getter与setter两个回调函数,可控制或监控对某个属性的访问.
既然它是控制对别的属性的访问去了,那么它本身没有数据.

var c = {
    _id: 1313, // 下划线开头, 语义上表示不能直接访问.
    get id(){
        console.log('取值',this._id);
        return this._id;
    },
    set id(val){
        console.log('存值', val);
        this._id = val;
    }
};
c.id=9090;
console.log(c.id);
// 存值 9090
// 取值 9090
// 9090
console.log(c._id); //9090  不通过访问器属性直接访问  

注意一下: ‘id‘ 这个访问器属性应该是可枚举的(没通过defineProperty定义),‘id‘ ‘_id‘都会遍历到:

console.log(JSON.stringify(c)); // stringify也是遍历取值
// 取值 9090
// {"_id":9090,"id":9090}

console.log(c); //{ _id: 9090, id: [Getter/Setter] }
通过defineProperty来设置访问器属性

访问器属性也是属性,也能像其它属性那样通过defineProperty来设置,不同的是,它没有value,而是get/set

Object.defineProperty(c,'ID',{
    set:function(val){
        console.log('存值ID', val);
        this._id = val;
    },
    get:function(val){
        console.log('取值ID',this._id);
        return this._id;
    },
    enumerable:false, //默认false
    configurable:true  // 默认false
});
访问器属性和数据属性结合
var c = {
    get id(){
        console.log('取值',this._id);
        return this._id;
    },
    set id(val){
        console.log('存值', val);
        this._id = val;
    }
};
Object.defineProperty(c,'_id',{  // 内部属性不被枚举才对嘛
    value:110,
    writable:false,
    enumerable:false, //默认false
    configurable:true  // 默认false
});
console.log(JSON.stringify(c));
 //取值 110
//{"id":110}

原文地址:https://www.cnblogs.com/ShawSpring/p/10806841.html

时间: 2024-11-08 21:38:25

js 属性的那些事的相关文章

js属性扩展,继承,属性查找

JavaScript 是一种基于原型的面向对象语言 在 javaScript 中,每个对象都有一个它的原型(prototype)对象的引用,这个原型对象又有自己的原型,直到某个对象的原型为 null 为止,这种一级一级的链结构就称为原型链(prototype chain).比如 定义一个object对象var o={},它的原型为Object.prototype,而Object.prototype的原型为null 下面为示例代码 <script type="text/javascript&

js属性

1.属性的操作方式 * 1..表示的意思 * 元素.属性名 * 如果属性是单一属性,用点操作符是取不到的,而且还会报错 * 如果想要用点操作符获取带横杠的属性,那首先要把横杠去掉,然后把横杠后面的第一个字母大写 * 2.[] 表示的意思 * 如果属性中带横杠,用[]的方式去操作属性 * []既可以操作符合变量命名规则的属性,也可以操作不符合变量命名规则的属性 <!DOCTYPE html> <html lang="en"> <head> <me

关于对js属性的测试

众所周知,DOM定义了一个Node接口(该接口由DOM中所有节点类型实现).常见的nodeType有3种:1(元素节点).2(属性节点).3(文本节点).我们可以通过获取元素来测试: 即:var oDiv=dcoument.getElementById(id); alert(oDiv.nodeType);//1 一切进行得很顺利也返回了自己想要的结果,接下来我们来看一段代码.对于刚接触不久的同学可能会范一种错误. 即:alert(oDiv.id.nodeType);又或者alert(oDiv.g

原生js与iframe一些事

因为sem推广总是提出一些让人吐血的需求,类似于用A链接访问B链接的内容,pc跟无线又要区分不同页面,区域的不同又要显示的内容不同等等,哎呀妈妈喂,净瞎折腾. 这一次的需求是打开A链接,mobile显示B链接的内容,pc显示C链接的内容,因为访问链接不能变.因此我首先想到的就是用iframe了. 本文的前提是iframe同域,即不存在跨域情况,页面没考虑IE兼容 A.html模板大概就是下面酱紫啦: {if $flag eq 'mobile'} <p class="title"

JS中字符串那些事~

1:字符串 JS中的任何数据类型都可以当作对象来看.所以string既是基本数据类型,又是对象. 2:声明字符串 var sStr = '字符串';(常用) var oStr = new String('字符串'); 3:字符串属性 1.length 计算字符串的长度(不区分中英文). 2.constructor 对象的构造函数. Sstr.constrouctor:它的对象仍然是String构造函数 4:字符串方法 1.myStr.charAt(num)  //从0开始 返回在指定位置的字符.

JS属性操作

1.属性写操作:添加.替换.修改 元素.属性名=新的值 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input id="btn" type="button" value="按钮" /> </

js入门 关于js属性及其数据类型(详解)

1. js的本质就是处理数据.数据来自于后台的数据库. 所以变量就起到一个临时存储数据的作用. ECMAScript制定了js的数据类型. 数据类型有哪些? 1. 字符串   String 2. 数字    Number 3. 布尔    Boolean 4. Null     空 5. Undefined 6. Object   对象 Array 数组   json   function  函数  日期 数字对象等 上面红色的叫基本数据类型. Var s="hello"; var s

JS之DOM那些事

DOM 是 Document Object Model(文档对象模型)的缩写.DOM分为核心DOM.XML DOM.HTML DOM,我们接触的主要是HTML DOM,HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法.换言之,HTML DOM 是关于如何获取.修改.添加或删除 HTML 元素的标准.在 HTML DOM 中,所有内容都是节点. DOM节点:节点在文档中以节点树的形式存在,如图: 节点分为12种不同类型,常用的有元素节点(1).属性节点(2).文本节点(

js 手机端触发事事件、javascript手机端/移动端触发事件

处理Touch事件能让你跟踪用户的每一根手指的位置.你可以绑定以下四种Touch事件: 1 2 3 4 touchstart:  // 手指放到屏幕上的时候触发  touchmove:  // 手指在屏幕上移动的时候触发  touchend:  // 手指从屏幕上拿起的时候触发  touchcancel:  // 系统取消touch事件的时候触发.至于系统什么时候会取消,不详 1 2 3 4 client / clientY:// 触摸点相对于浏览器窗口viewport的位置  pageX /