JS言语精炼--对象

这篇文章算是我职业生涯中的第一篇手艺博文吧,有些处所能够表达得不是很好,还望人人多多见谅哈^_^!

正文

JavaScript的简朴范例有数字、字符串、布尔值(true、false)、null值和underfind值,其他一切的值都是对象。

数字、字符串和布尔值“貌似”是对象,由于它们都具有要领,然则它们是不可变的。而JavaScript中的对象是可控的键控鸠合

在JavaScript中,数组是对象,函数是对象,正则表达式是对象,固然,对象天然也是对象。

对象是属性的容器,个中每一个属性都具有名字和值(name-value)。属性名可所以包括字符串在内的恣意字符串,属性值可所以除undefined值以外的恣意值。

JavaScript中的对象是无种别(class-free)的,它对新属性的名字和值没有束缚。对象合适用于网络和治理数据。对象能够包括其他对象,所以它们能够轻易的示意成树形或图形构造。

JavaScript包括一个原型链特征(这是JS对象中很主要的一个特征,细致用法今后我会发一篇针对原型链及其用法的文章举行特地申明),许可对象继续另一个对象的属性,准确地运用它能削减对象初始化的时刻和内存消耗。

1. 对象字面量

对象字面量,供应了一种非常轻易的建立新对象值得示意法,即包围在一对花括号中的零个或多个“名/值”对(也称为键值对),它能够涌现在任何许可表达式涌现的处所。

javascriptvar empty_object = {};
var batman = {
    'first-name': 'Bruce',
    'last-name': 'Wayne'
};

属性名可所以包括空字符串在内的任何字符串,不过,一个正当的变量标识符,不能是保留字,虽然不强挪用引号括住,然则,像“first-name”、“first name”这类含有“-”或是空格的属性名,是必需加上引号括住的。逗号用来分开多个“名/值”对。

属性值能够从包括另一个对象字面量在内的恣意表达式中获得,而对象是可嵌套的。

javascriptvar flight = {
    airline: 'Domestic',
    number: 1024,
    departure: {
        IATA: 'SZ',
        time: '2015-08-03 15:00:00',
        city: 'shenzhen'
    },
    arrival: {
        IATA: 'BJ',
        time: '2015-08-04 00:00:00',
        city: 'beijing'
    }
};

2. 检索

要检索对象中包括的值(或属性值或要领或别的),能够采用在 [] 后缀中括住一个字符串表达式的体式格局,假如字符串表达式是一个正当js标识符且不为保留字的常数,那末优先斟酌用 . 示意法,由于它更紧凑且可读性更好。

javascriptbatman['first-name']    // "Bruce"
flight.departure.city   // "shenzhen"

假如你尝试检索一个并不存在的成员元素的值(这里的属性表达式是严厉辨别大小写的),将返回一个undefined值。

javascriptbatman['middle-name']   // undefined
flight.status           // undefined
batman['FIRST-NAME']    // undefined

|| 运算符能够用来添补默认值:

javascriptvar middle = batman['middle-name'] || '(none)';
var status = flight.status || 'unknown';

尝试检索一个undefined值将会致使TypeError非常,这能够经由历程 && 运算符来防止毛病。

javascriptflight.equipment                             // undefined
flight.equipment.model                       // throw "TypeError"
flight.equipment && flight.equipment.model   // undefined

3. 更新

对象中的值能够经由历程赋值语句来更新。

假如属性名已存在于对象中,那末这个属性值将被替代。

javascriptbatman['first-name'] = 'Damian';

假如对象之前并没有这个属性名,那末该属性将会被扩充到该对象中。

javascriptbatman['middle-name'] = 'AI';
batman['nickname'] = 'Robin';
flight.equipment = {
    model: 'Boeing 777'
};
flight.status = 'overdue';

4. 援用

对象经由历程援用来通报,它们永久不会被拷贝。

javascriptvar x = batman;
x.nickname = 'Joker';
var nick = batman.nickname;  // 由于x和batman是指向同一个对象的援用,所以nick为"Joker"
var a = {},b = {},c = {};    // a、b、c 每一个都离别援用一个差别的空对象
a = b = c = {};              // a、b、c 都援用一个雷同的空对象

5. 原型

每一个对象都邑衔接到一个原型对象,而且它能够从中继续属性。一切经由历程字面量建立的对象,都衔接到 Object.prototype 这个JS中的规范的对象。

当建立一个新对象时,能够挑选某个对象作为它的原型,给Object增添一个beget要领,这个beget要领建立一个运用原对象作为其原型的新对象,这个我们今后会在特地的博文做细致相识。

javascriptif(typeof Object.beget !== 'function'){
    Object.beget = function(o){
        var F = function(){};
        F.prototype = o;
        return new F();
    };
};

var next_batman = Object.beget(batman);

原型衔接在更新时是不起作用的,当我们对某个对象做出转变时,不会触及到该对象的原型:

javascriptnext_batman['first-name'] = 'Damian55';
next_batman['middle-name'] = 'Ai22';
next_batman.nickname = 'Robin5';

原型衔接只要在检索值的时刻才会被用到。假如我们尝试去猎取对象的某个属性值,且该对象没有该属性名,那末,JS会试着从原型对象中猎取属性值,假如谁人原型对象也没有该属性,则再从它的原型中寻觅,以此类推,直到末了抵达尽头Object.prototype,若想要的属性完整不存在于原型链中,则返回undefined值,这个历程称为托付

原型关联是一种动态的关联,假如我们在原型中增加一个新的属性,该属性会立即对一切基于该原型建立的对象可见。

javascriptbatman.profession = 'JSL';
next_batman.profession;      // 'JSL'

6. 反射

搜检对象并确认对象有什么属性,能够去检索该属性并考证获得的值。而肯定属性的范例,能够运用typeof操作符。

javascripttypeof flight.number        // 'number'
typeof flight.status        // 'string'
typeof flight.arrival       // 'object'
typeof flight.manifast      // 'undefined'

请务必注重原型链中的任何属性也会发生一个值:

javascripttypeof flight.toString      // 'function'
typeof flight.constructor   // 'function'

有两种要领去处置惩罚这些不需要的属性:

  • 让你的递次搜检并剔除函数值,一般来说,做反射的目的是数据,因而个中一些值能够会是函数。
  • 运用hasOwnProperty要领,假如对象具有自力属性,它将返回true。

别的,hasOwnProperty要领不会搜检原型链。

javascriptflight.hasOwnProperty('number');        // true
flight.hasOwnProperty('constructor');   // false

7. 罗列

for in 语句可用来遍历一个对象中的一切属性名,固然,也包括函数和我们能够不关心的原型中的属性,所以我们有必要过滤掉不必要的值。
最经常使用的过滤器(即过滤原型中的属性)是hasOwnProperty要领,以及运用typeof来消除函数:

javascriptvar name;
for(name in next_batman){
    if(typeof next_batman[name] !== 'function'){
        document.writeln(name + ': ' + next_batman[name]);
    }
}

以上,属性名涌现的递次是不肯定的,因而要想确保属性以特定的递次涌现,最好是完整防止运用 for in 语句,而是建立一个数组,在个中以准确的递次包括属性名:

javascriptvar i;
var properties = ['first-name','middle-name','last-name','profession'];
for(i = 0;i < properties.length;i ++){
    document.writeln(properties[i] + ': ' + next_batman[properties[i]]);
}

经由历程运用一般for而不是for in ,能够获得我们想要的属性,而不必忧郁能够发掘出原型链中的属性,并按准确的递次获得它们的值。

8. 删除

delete运算符能够用来删除对象的属性,它将会移除该对象的肯定包括的属性,它不会触及原型链中的任何对象。

删除对象的属性能够会让来自原型链中的属性显现出来。

javascriptnext_batman.nickname        // 'Robin5'
// 删除next_batman的nickname属性,从而暴露出原型的nickname的属性值
delete next_batman.nickname; 
next_batman.nickname;       // 'Robin'

9. 削减全局变量污染

JS能够随便定义可保存一切运用资本的全局变量,不幸的是,全局变量会减弱递次的灵活性,所以应当防止。

最小化运用全局变量的一个要领是在你的运用中只建立唯一一个全局变量:

javascriptvar MyApp = {};

该变量此时变成了你的运用容器:

javascriptMyApp.batman = {
    'first-name': 'Bruce',
    'last-name': 'Wayne'
};

MyApp.flight = {
    airline: 'Domestic',
    number: 1024,
    departure: {
        IATA: 'SZ',
        time: '2015-08-03 15:00:00',
        city: 'shenzhen'
    },
    arrival: {
        IATA: 'BJ',
        time: '2015-08-04 00:00:00',
        city: 'beijing'
    }
};

只要把多个全局变量都整顿在同一个定名空间下,你将明显下降与其他运用递次、组件或类库之间发生蹩脚的相互影响(即耦合度高)的能够性,也使其变得更轻易浏览,由于MyApp.batman指向的时顶层构造。固然,也能够运用闭包来举行信息隐蔽,它是另一种有用削减全局污染的要领。

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