javascript 语言精粹 学习笔记(二)

javascript 语言精粹 学习笔记(二)

接着我们来看看,表达式之后的部分。

表达式

基本的表达式,无非是字面量值、变量、内置的值(true、false、null、undefined、NaN、Infinity)、以new开头的调用表达式、delete开头的属性提取表达式、以前置运算符作为前导的表达式、或者由一下形式构成的:

  • expression + infix operator + expression
  • expression ? expression : expression
  • 函数调用
  • 函数提取表达式

之后就是表达式结合的重要规则了,优先级由上往下降低:

.   []  ()                          提取属性与调用函数

delete  new typeof  +   -   !       一元运算符

*   /   %                           乘法、除法、求余

+   -                               加法/连接、减法

>=    <=    >    <                  不等式运算符

===   !==                           等式运算符

&&                                  逻辑与

||                                  逻辑或

?:                                  三元
  • typeof运算符产生的值有’number’、’string’、’boolean’、’undefined’、’function’、’object’。null的typeof结果是object。
  • +运算符,只在两个运算数都是数字的情况下,才起到加法的作用,不然的话,就是字符串连接的作用。
  • /运算符,即使是在两个运算数都是整数的情况下,也可能产生非整数结果。毕竟前面提到了js默认的数字类型是64位的浮点数

字面量

对象字面量里的属性名,可以是标识符或字符串。这些名字被当做字面量名而不是变量名来对待,所以对象的属性名在编译时才能知道。属性的值就是表达式。

函数

这一章对于函数只是略微介绍了一下,详细的内容在之后的章节会细说。

第三章 对象

对于丑陋的事物,爱会闭目无视。

——威廉·莎士比亚《维洛那二绅士》(The Two Gentlemen of Verona)

  • js的简单数据类型包括数字、字符串、布尔值(true、false)、null值和undefined值。其他所有的值都是对象。

  • 数组、字符串、布尔值看上去很像对象,以为他们都有可用的方法,但他们是不可变的。js中的对象是可变的键控集合。(至于为什么不是对象,还拥有方法,这个可以去翻阅《javascript高级程序设计》中的内置对象那一章,其中讲了几个基本类型是如何变成包装类型调用方法的)。

  • 对象是属性的集合,属性名可以是包括空字符串在内的任何字符串。

  • js里的对象是无类型(class-free)的。

  • js包含叫做原型链的特性,允许对象继承另一个对象的属性(这里的继承和传统面向对象的继承是有所区别的,不能照搬概念)。正确使用可以减少对象初始化消耗的时间和内存。

对象字面量

对象字面量就是一对花括号中的零或多个“名/值”对。对象字面量可以出现在任何允许表达式出现的地方。对象是可嵌套的,属性的值也可以是另一个对象字面量。

如果属性名是一个合法的js标识符且不是保留字,所以不强制用引号括住属性名。

检索

  • 可以采用[]后缀括住一个字符串表达式,来检索对象里的值。不过,在符合js标识符命名规范下,优先使用 . 表示法,因为更紧凑可读性更好。
  • 如果检索不存在的成员属性,返回undefined。
  • ||运算符可以用来填充默认值。

    var middle = stooge["middle-name"] || "(none)";
    var status = flight.status || "unknown";
    
  • 尝试从undefined的成员属性中取值将会导致TypeError,这时可以通过&&运算符来避免错误。

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

更新

  • 对象里的值可以被赋值语句来更新,如果已经存在于对象里,那么就会被替换。
  • 如果对象之前没有那个属性,该属性就被扩充到对象里。

引用

对象通过引用来传递,永远不会被复制。

原型

  • 每个对象都会链接到一个原型对象上,从中继承属性。
  • 所有对象字面量创建的对象都能连接到Object.prototype,这是js的标配对象
  • 当创建新对象时,你可以选择某个对象作为它的原型。Object.create方法,创建一个使用原对象作为其原型的新对象。

    if(typeof Object.beget !== 'function') {
        Object.create = function(o) {
            var F = function (o) {};
            F.prototype = o;
            return new F();
        };
    }
    var another_stooge = Object.create(stooge);
    
  • 原型连接在更新时是不起作用的。当对某个对象做出改变时,不会触及该对象的原型。

  • 委托:当尝试去获取某个对象的属性值时,但该对象没有此属性名时,js会尝试从原型对象中获取属性值。如果那个原型对象都没有,再从它的原型中检索,直到最后到达Object.prototype。如果想要的完全不存在原型链中,结果是undefined。
  • 原型关系是一种动态关系,添加新的属性到原型中,该属性会立即对所有基于该原型创建的对象可见。

反射

  • typeof操作符对于确定属性的类型很有帮助
  • 请注意原型链中的任何属性都会产生值

    typeof flight.toString         //'function'
    typeof flight.constructor      //'function'
    
  • 有两种方法可以处理掉这些不需要的属性。第一个是让你的程序做检查并丢弃这些值为函数的属性。但是,一些值也可能是函数。

  • 另一个方法是使用hasOwnProperty方法,这个方法不会检查原型链。

枚举

  • for in语句用来遍历一个对象中的所有属性名,但是这会包括函数和原型中的属性。过滤掉不想要的属性的常用办法,是hasOwnProperty和typeof。

    vaf name;
    for (name in another_stooge){
        if(typeof another_stooge[name] !== 'function'){
            document.writeln(name + ': ' + another_stooge[name]);
        }
    }
    
  • 因为遍历的顺序是不确定的,所以为了让属性以特定的顺序出现,最好的办法是完全避免使用for in语句,而是创建一个数组,在其中以正确的顺序包含属性名:

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

删除

  • delete运算符只能用来删除对象的属性。如果对象包含该属性,属性会被移除。
  • 它不会触及原型链中的任何对象
  • 删除对象的属性可能会让原型链中的同名属性暴露出来。

    another_stooge.nickname       //'Moe'
    //删除该对象的nickname属性,从而暴露出原型的nickname属性
    delete another_stooge.nickname;
    
    another_stooge.nickname       //'Curly'
    

减少全局变量的污染

js可以很灵活的定义全局变量,来容纳所有的资源。遗憾的是,全局变量削弱了程序的灵活性,应该避免使用。

最小化使用全局变量的方法之一:创建唯一的全局变量,作为应用的容器。

eg.下一次是函数部分的笔记

你可能感兴趣的:(javascript)