JavaScript权威指南(第6版)

第1章   JavaScript概述

1、存在"<="(小于等于)和">=(大于等于)"两种运算符


第3章   类型、值和变量

1.我们通常将对象称为引用类型。对象值都是引用,对象的比较均是引用的比较:当且仅当它们引用同一个基对象时,它们才相等。

var a = [];//定义一个引用空数组的变量a

var b = [];//变量b引用同一个数组

b[0] = 1;//通过变量b来修改引用的数组

a[0]; // =>1 ,变量a也会修改

a === b ;// => true,a和b引用同一个数组,因此它们相等。


就像刚看到的如上代码,将对象(或数组)赋值给一个变量,仅仅是赋值的引用值:对象本身并没有复制一次。如果你想得到一个对象或数组的副本,则必须显式复制对象的每个属性或数组的每个元素。下面这个例子则是通过循环来完成数组复制:

var a = ['a','b','c']; //待复制的数组

var b = []; //复制到的目标空数组

for(var i = 0; i<a.length; i++){ //循环遍历所以元素

    b[i] = a[i]; //将元素值复制到b中

}


2.(3.10.1)函数作用域和声明提前

在一些类似C语言的编程语言中,花括号内的每一段代码都有各自的作用域,而且变量在声明它们的代码段之外是不可见的,我们成为块级作用域,而JavaScript中没有块级作用域。JavaScript取而代之的使用了函数作用域:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。


在如下所示代码中,在不同的位置定义了变量i,j和k,它们都在同一个作用域内——这三个变量在函数体内均是有定义的。

function test(o) {

   var i = 0; // i在整个函数体内均是由定义的

   if(typeof o == 'object' ) {

        var j = 0; //j在函数体内是有定义的,不仅仅是在这个代码段内

        for(var k = 0; k < 10; k++){  //k在函数体内是有定义的,不仅是在循环内

                 console.log(k); //输出数字0-9

        }

        console.log(k); // k已经定义了,输出10

   }

   console.log(j); // j已经定义了,但可能没有初始化

}


JavaScript 的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味着变量在声明之前甚至已经可用。JavaScript的这个特性被非正式地称为声明提前,即JavaScript函数里声明的所有变量(但不涉及赋值)都被“提前”至函数体的顶部,看一下如下代码:

var scope = 'global';

function f(){

    console.log(scope); //输出'undefined',而不是'global'

    var scope = 'local'; //变量在这里赋初始值,但变量本身在函数体内任何地方均是有定义的

   console.log(scope); //输出'local'

}


你可能会误以为函数中的第一行会输出‘global’,因为代码还没有执行到var语句声明局部变量的地方。其实不然,由于函数作用域的特性,局部变量在整个函数体始终是有定义的,也就是说,在函数体内局部变量遮盖了同名全局变量。尽管如此,只有在程序执行到var语句的时候,局部变量才会被真正赋值。因此,上述过程等价于:将函数内的声明“提前”至函数体顶部,同时变量初始化留在原来的位置:

function f(){

   var scope;   //在函数顶部声明了局部变量

   console.log(scope);  //变量存在,但其值是"undefined"

   scope = 'local';  //这里将其初始化并赋值

   console.log(scope);  //这里它具有了我们所期望的值

}

在具有块级作用域的编程语言中,在狭小的作用域里让变量声明和使用变量的代码尽可能靠近彼此,通常来讲,这是一个非常不错的编程习惯。由于JavaScript没有块级作用域,因此一些程序员特意将变量声明放在函数体顶部,而不是将声明靠近放在使用变量之处。这种做法使得他们的源代码非常清晰地反映了真实的变量作用域。


3.(3.10.2)作为属性的变量

当声明一个JavaScript全局变量时,实际上时定义了全局对象的一个属性,当使用var声明一个变量时,创建的这个属性是不可配置的,也就是说这个变量无法通过delete运算符删除。可能你已经注意到了,如果你没有使用严格模式并给一个未声明的变量赋值的话,JavaScript会自动创建一个全局变量。以这种方式创建的变量是全局对象的正常的可配置属性,并可以删除它们:

var truevar = 1; //声明一个不可删除的全局变量

fakevar = 2; //创建全局对象的一个可删除的属性

this.fakevar2 = 3; //同上

delete truevar  // =>false:变量并没有被删除

delete fakevar // => true: 变量被删除

delete this.fakevar2 // => true: 变量被删除



第4章 表达式和运算符

4.4属性访问表达式

属性访问表达式运算得到一个对象属性或一个数组元素的值。JavaScript为属性访问定义了两种语法:

expression.identifier

expression[expression]

第一种写法是一个表达式后跟随一个句点和标识符。表达式指定对象,标识符则指定需要访问的属性的名称。第二种写法是使用方括号,方括号内是另外一个表达式(这种方法适用于对象和数组)。第二个表达式指定要访问的属性的名称或者代表要访问数组元素的索引。


4.9相等和不相等运算符

NaN和其他任何值都是不相等的,包括它本身。通过x !== x来判断x是否为NaN,只有在x为NaN的时候,这个表达式的值才为true


4.13.3 delete运算符

var o = [1,2,3]; //定义一个数组

delete a[2]; //删除最后一个数组元素

2 in a; // => false,元素2在数组中已经不存在了

a.length // => 3,注意,数组长度并没有改变,经上一行代码删除了这个元素,但删除操作留下了一个“洞”,实际上并没有修改数组的长度,因此a数组的长度仍然是3


注意:通过var声明的变量是无法通过delete删除的


第5章 语句

5.5.4 for/in

for/in语句也使用for关键字,但它是和常规的for循环完全不同的一类循环。for/in循环语句的语法

如下:

for(variable in object)

    statement

在执行for/in语句的过程中,JavaScript解释器首先计算object表达式。如果表达式为null或者undefined,JavaScript解释器将会跳过循环并执行后续的代码。如果表达式等于一个原始值,这个原始值将会转换为与之对应的包装对象。否则,expression本身已经是对象了。JavaScript会依次枚举对象的属性来执行循环。然而在每次循环之前,JavaScript都会先计算variable表达式的值,并将属性名(一个字符串)赋值给它。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值