hi,你好!欢迎访问本站!登录
本站由简数采集腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 文章 - 后端开发 - 正文 看Cosplay古风插画小姐姐,合集图集打包下载:炫龙网 · 炫龙图库

JavaScript中对象属性详解_WEB前端开发

2019-11-29后端开发ki4网20°c
A+ A-

JavaScript 中的对象观点确实很轻易让人疑心。看下面一个例子:

var strPrimitive = "I'm mamacat";
typeof strPrimitive; // "string"
strPrimitive instanceof String; // false

var strObject = new String("I'm mamacat");
typeof strObject; // "object"
strObject instanceof String; // true

strPrimitive.substr(8, 3); // "cat"

一样的字符串赋值到对象,一会儿是字符串范例一会儿是对象,而明显不是对象范例的变量照样可以运用对象属性,为何会如许呢?

【相干课程引荐:JavaScript视频教程】

范例和内置对象

JavaScript 中一共有六种重要(言语)范例,即 string, number, boolean, null, undefined 和 object,个中前五个基础范例都不是对象(对 null 举行 typeof 获得的是 "object",这是言语自身的 BUG)。而在此之外,则有许多迥殊的对象子范例,比方数组、函数和内置对象等。

有些内置对象的名字看着和简朴基础范例一样,就比方 String,Boolean,Object 之类。这些内置对象从表现情势看就和别的面向对象言语中的“类”观点差不多,而正如上篇文章所属,它们现实使只是一些能被用来组织一个对应子范例的内置函数罢了(不要疑心,函数也是对象,这里并不矛盾)。因而就可以回到最初的例子,strObject 是由内置函数/内置对象 String 所组织的变量,对应 String 子范例,所以它是一个对象,而 strPrimitive 则是一个原始字面值罢了。

固然,上面例子中最下面我们看上去对 strPrimitive 调用了 substr() 函数,这里则是因为,JavaScript 引擎会在须要时,把原始字面量转换成对应的对象,而转换以后我们天然就可以运用属性接见对应的要领了。

对象属性

那末,就上方的例子而言,String 对象实例就会有 substr() 函数可以用,但依据之前的文章可以晓得,这些“函数”自身并不属于某个对象,而这些函数本质是对应对象的一个属性。固然,即使我们说某种范例的对象自身具有种种属性,现实上这些属性也多是各自自力存在的,只不过以援用的情势关联在了一同罢了,这和之前相识的内容也并不矛盾。这些被关联起来的东西,被称为对象的 属性。

对象的复制

插播一条快报,只管之前的文章提到过,上方也又一次反复强调过属性只是以援用的情势关联起来的自力存在,我们偶然依然会“理所应该”的以为属性是对象的一部分,而最轻易因而踩坑的处所之一就是对象的复制了。细致思索即可晓得,当我们复制对象时,因为其属性自身只是援用关联,故“复制”获得的对象所包括的属性援用指向的和底本对象的属性援用着实照样同一个位置:

var ori = { a : 1};
var ori_copy = ori;
ori.a = 61;
ori_copy.a; // 61

明显这极大概和我们的希冀不一样,而我们想要真正的拷贝对象则没有圆满适用性的计划,许多时刻的通例做法则是把对象序列化一下,然后再以此反序列化获得新的对象来完成对象的拷贝(比方运用 json)。ES6 中新增了 Object.assign() 来举行对象的浅拷贝,做法是把对象的一切可罗列属性等号赋值到新对象中。不过仍需注重的是,等号赋值并不会赋值属性的元信息(属性描述符,后述),在须要的情况下应该迥殊注意。

属性接见和数组

接见对象所关联的属性的体式格局即经由过程 . 或许 [] 操纵符举行接见,obj.a 和 obj["a"] 接见的属性本质上是一样的,而这两种接见情势的辨别也只要接见的属性称号里能不能有新鲜的标记罢了。[] 操纵符内扔的是个字符串,现实上属性名也永远都是字符串。固然,这个观点大概比较不测的就是,数组的下标接见着实并非破例,数字照样被转换成了字符串才被运用的。

// 对象的属性接见:
var tejilang = {1 : "Teji Wolf"};
tejilang instanceof Array; // false
tejilang["1"]; // "Teji Wolf"
tejilang[1]; // "Teji Wolf"

// 这回保证它是 Array
var macat = ["codingcat"];
macat instanceof Array; // true
macat.length; // 1
macat[0]; // "codingcat"
macat["0"]; // "codingcat"
macat.length = 20;
macat; // (20) ["codingcat", empty × 19]

数组下标既然不属破例情况,那数组对象必定有别的属性掌握数组自身的行动,比方上例中,macat 数组的长度就是 length 属性所表现的,经由过程修正它的值也就转变了对象自身对外的表现情势。固然,因为数组自身就是对象,所以我们照样可以把数组当键值对来用,只是这类做法一般是没有意义且会让人觉得疑心的。JavaScript 引擎一般都依据对象的范例做了差别水平的优化,故除了代码逻辑可读性外,合理的运用也是多少可以改良机能的。

可以经由过程字符接见属性照样存在一些别的优点的,比方 ES6 的可计算属性名。固然 ES6 不在本文的关注范围内,所以这里就不再议论了。

属性描述符

偶然我们大概不愿望某个属性被随便修正,偶然候我们须要分外设置一些属性的信息,自 ES5 起,一切的属性就都具有了“属性描述符”(Property Descriptor)来掌握属性自身的这些元信息。

数据描述符

来看这个例子:

var chris = {};
Object.defineProperty(chris, "IQ", {
    value: 228,
    writable: false,
    configurable: true,
    enumerable: true
});
chris.IQ = 61; // 寂静失利了,假如是严厉形式则会 TypeError
chris.IQ; // 228

经由过程 defineProperty 可以对一个对象的属性设置其对应的属性描述符(元信息),而属性描述符则包括接见描述符和数据描述符,上面的例子中,defineProperty 的第三个参数就定义了数据的多少数据描述符,个中 writable 示意可写,configurable 示意属性是不是可设置(注重,修正成不可设置是单向操纵),enumerable 则示意属性是不是应该出现在罗列中,比方 for..in 中。

明显我们可以经由过程属性描述符完成对属性的庇护,而同时也存在一些轻易函数来做近似的事。如 Object.preventExtensions() 会保存原有属性但制止增加新属性,Object.seal() 会密封对象,在制止增加新属性的基础上把原有属性标记为不可设置,Object.freeze() 会凝结对象,即在密封的基础上把数据接见属性标记为不可写。

[[Get]], [[Put]] 和接见描述符

在我们接见和赋值一个对象的属性时,现实上是经由过程 [[Get]] 和 [[Put]] 操纵举行的,比方属性接见时,[[Get]] 会先找有无这个属性,假如没有则会遍历对象的 [[Prototype]] 链(原型链,此次不谈这个观点)来找,着实找不到则返回 undefined 。而这个行动现实是许可我们经由过程设置 getter (get())和 setter (set())函数来转变的,它们被称为 接见描述符。

当我们供应接见描述符时,对应的接见操纵就不再遭到 value writable 属性的影响了,别的须要注重的是,只管它们也是属性描述符,但定义 getter 和 setter 并不请求一定要经由过程 defineProperty 设置:

var obj = {
    get a() { // 给 a 属性定义 getter
        return this._a_;
    },
    set a(val) { // a 属性的 setter
        this._a_ = val * 2;
    }
}

obj.a = 2;
obj.a; // 4

属性存在性

因为属性的值也多是 undefined,不存在的属性直接接见获得的也是 undefined,所以直接经由过程简朴的属性接见是没法辨别是不是存在的,这时候我们即可经由过程 in 或许 hasOwnProperty() 搜检属性是不是存在对象中了:

var obj = {a : 2};
"a" in obj; // true
obj.hasOwnProperty("a"); // true

只管仍没有讲到原型链的观点,这里依然应注重,in 操纵符会搜检原型链中是不是存在属性,而 hasOwnProperty 则不会。别的在一些情况下,有的对象会没有 hasOwnProperty 这个属性(此处不提缘由),这时候可以用过 Object.prototype.hasOwnProperty.call(objName, propertyName) 来完成搜检。

本文来自 js教程 栏目,迎接进修!

以上就是JavaScript中对象属性详解的细致内容,更多请关注ki4网别的相干文章!

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  选择分享方式
  移步手机端
JavaScript中对象属性详解_WEB前端开发

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
标签:

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>