Professional JavaScript for Web Developers 读书笔记(三)

来源:互联网 发布:淘宝卖家库存管理 编辑:程序博客网 时间:2024/05/16 05:57

  • 基本概念
    • 语法
      • 大小写区分
      • 标识符
      • 注释
      • 严格模式
      • 语句
    • 关键字和保留字
    • 变量
    • 数据类型
      • typeof操作符
      • Undefined类型
      • Null类型
      • Boolean类型
      • Number类型
      • String类型
      • Object类型
    • 操作符号
    • 一元操作符
      • 位操作符
      • 布尔操作符
      • 乘性操作符
      • 加性操作符
      • 关系操作符
      • 相等操作符
      • 条件操作符
      • 赋值操作符
      • 逗号操作符
    • 语句
    • 函数
      • 理解参数
      • 没有重载
    • 小结

基本概念

此章节学习JavaScript最基本的工作原理

语法

大小写区分

变量 Test 与 test 表示不同的变量

标识符

标识符就是变量,函数的名字,或者函数的参数,有下列特征
- 第一个字符必须是字母,下划线,或者$;
- 其他字符可以是字母,下划线或数字 .

注释

// 单行
/*
多行注释
*/

严格模式

strict mode
设立”严格模式“的目的,主要有以下几个。

1.明确禁止一些不合理、不严谨的语法,减少JavaScript的一些怪异行为。2.增加更多报错的场合,消除代码运行的一些不安全之处,保证代码运行的安全。3.提高编译器效率,增加运行速度。4. 为未来新版本的JavaScript做好铺垫。  

“严格模式”体现了JavaScript更合理、更安全、更严谨的发展方向,要使用严格模式可以在顶部添加代码:”use strict”;在函数内部的上方包含这条编译指示,也可以指定函数在严格模式下执行:

function doSomething(){    "use strict";    //函数体}

语句

以一个 ; 作为一条语句的结束,不是必须,建议加上。
在控制语句中建议使用下列代码块,加强编码意图:

if (test)alert(test); // 有效但容易出错,不要使用if (test){ // 推荐使用alert(test);}

关键字和保留字

ECMA-262 描述了一组具有特定用途的关键字,这些关键字可用于表示控制语句的开始或结束,或者用于执行特定操作等,避免使用这些作为标识符。

关键字break     do       instanceof  typeofcase      else     new         varcatch     finally  return      voidcontinue  for      switch      whiledebugger* function this        withdefault   if       throwdelete    in       try保留字abstract    enum       int          shortboolean     export     interface    staticbyte        extends    long super   throwschar        final      native       publicclass       float      package      transientconst       goto       private      volatiledebugger    implements protected    double      import      synchronized

变量

1.ECMAScript 的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据:

var message;

2.像这样未经过初始化的变量,会保存一个特殊的值——undefined,也设置变量的值

var message = "hi";message = 100; // 有效,但不推荐

3.var定义的变量将成为定义该变量的作用域中的局部变量,注意下列test函数中的message变量,建议使用var定义避免不必要的混乱.

function test(){var message = "hi"; // 局部变量}test();alert(message); // 错误!
function test(){message = "hi"; // 全局变量}test();alert(message); // "hi"

数据类型

ECMAScript有五种基础数据类型,Undefined,Null,Boolean,Number和String,一种复杂数据类型Object,其由一组无序的名值对组成的。

typeof操作符

这一操作符可以检测给定变量的数据类型,如下列

var message = "some string";alert(typeof message); // "string"alert(typeof(message)); // "string"alert(typeof 95); // "number"

(注:null被认为是一个空的Object,typeof null返回的是object)

Undefined类型

Undefined 类型只有一个值,即特殊的undefined.

var message;var message = undefined; //等价alert(message == undefined); //true
var message; // 这个变量声明之后默认取得undefined 值// var age 这个变量并没有声明alert(message); // "undefined"alert(age); // 产生错误

未经初始化的值默认就会取得undefined 值,而尚未定义的变量会错误.

var message; // 这个变量声明之后默认取得undefined 值// var age 下面这个变量并没有声明alert(typeof message); // "undefined"alert(typeof age); // "undefined"

有趣的是对未初始化的变量执行typeof 操作符会返回undefined 值,而对未声明的变量执行typeof 操作符同样也会返回undefined 值.

Null类型

Null 类型是第二个只有一个值的数据类型,这个特殊的值是null.null 值表示一个空对象指针,而这也为什么typeof 操作符检测null 值时会返回”object”的原因.undefined 值是派生自null 值的,因此ECMA-262 规定对它们的相等性测试要返回true.

alert(null == undefined); //true

Boolean类型

Boolean类型只有两个字面值:true 和false(小写的false和true).要将一个值转换为其对应的Boolean 值,可以调用转型函数Boolean()

数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 “”(空字符串) Number 任何非零数字值(包括无穷大) 0和NaN Object 任何对象 null Undefined n/a undefined

(注:n/a(或N/A),是not applicable 的缩写,意思是“不适用”。)
转换规则对理解流控制语句十分有用,错误地使用一个对象而不是一个Boolean 值,就有可能彻底改变应用程序的流程。

var message = "Hello world!";if (message){alert("Value is true");}

字符串message 被自动转换成了对应的Boolean 值(true)。

Number类型

1.浮点数的概念.
JS中的数字都是用浮点数表示的,并规定使用IEEE 754 标准的双精度浮点数表示.IEEE 754 规定了两种基本浮点格式:单精度和双精度,除了十进制可以使用以外,八进制,十六进制也是可以使用的.
IEEE单精度格式具有24 位有效数字精度(包含符号号),并总共占用32 位。
IEEE双精度格式具有53 位有效数字精度(包含符号号),并总共占用64 位。

var octalNum1 = 070; // 八进制的56var octalNum2 = 079; // 无效的八进制数值——解析为79var hexNum1 = 0xA; // 十六进制的10

八进制字面量在严格模式下是无效的,十六进制字面值的前两位必须是0x,后跟任何十六进制数字(0~9 及A~F)。其中,字母A~F可以大写,也可以小写.
观察下列代码:

if (a + b == 0.3){ // 不要做这样的测试!alert("You got 0.3.");} // 结果并非返回true!

造成这样的原因是,十进制0.1的转化为二进制的二进制0.00011001100110011…(循环0011),因为尾数最多52位,所以实际存储为
0.00011001100110011001100110011001100110011001100110011001
而十进制0.2转化为二进制0.0011001100110011…(循环0011),尾数最多52位,所以实际存储为0.00110011001100110011001100110011001100110011001100110011
那么两者相加得:
0.00011001100110011001100110011001100110011001100110011001+
0.00110011001100110011001100110011001100110011001100110011=
0.01001100110011001100110011001100110011001100110011001100
转换成10进制之后得到:0.30000000000000004(转自知乎:刘浩博)
关于浮点数值计算会产生舍入误差的问题,有一点需要明确:这是使用基于IEEE754 数值的浮点计算的通病,ECMAScript 并非独此一家;其他使用相同数值格式的语言也存在这个问题。
2.数值范围
ECMAScript 并不能保存世界上所有的数值。ECMAScript 能够表示的最小数值保存在Number.MIN_VALUE 中——在大多数浏览器中,这个值是5e-324;能够表示的最大数值保存在Number.MAX_VALUE 中——在大多数浏览器中,这个值是1.7976931348623157e+308。如果某次计算的结果得到了一个超出JavaScript 数值范围的值,那么这个数值将被自动转换成特殊的Infinity 值。具体来说,如果这个数值是负数,则会被转换成-Infinity(负无穷),如果这个数值是正数,则会被转换成Infinity(正无穷)。

var result = Number.MAX_VALUE + Number.MAX_VALUE;alert(isFinite(result)); //false

要想确定一个数值是不是有穷的(换句话说,是不是位于最小和最大的数值之间),可以使用isFinite()函数。这个函数在参数位于最小与最大数值之间时会返回true
3. NaN
NaN,即非数值(Not a Number)是一个特殊的数值.
NaN 本身有两个非同寻常的特点。首先,任何涉及NaN 的操作(例如NaN/10)都会返回NaN,这个特点在多步计算中有可能导致问题。其次,NaN 与任何值都不相等,包括NaN 本身.
ECMAScript 定义了isNaN()函数。这个函数接受一个参数,该参数可以
是任何类型,而函数会帮我们确定这个参数是否“不是数值”.

alert(isNaN(NaN)); //truealert(isNaN(10)); //false(10 是一个数值)alert(isNaN("10")); //false(可以被转换成数值10)alert(isNaN("blue")); //true(不能转换成数值)alert(isNaN(true)); //false(可以被转换成数值1)

4 . 数值转换
有3 个函数可以把非数值转换为数值:Number()parseInt()parseFloat()。转型函数Number()可以用于任何数据类型,而另两个函数则专门用于把字符串转换成数值。

  • Number()函数的转换规则如下
  • 如果是Boolean 值,true 和false 将分别被转换为1 和0。
  • 如果是数字值,只是简单的传入和返回。
  • 如果是null 值,返回0。
  • 如果是undefined,返回NaN。
  • 如果是字符串,遵循下列规则:
    1. 如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即”1”会变成1,”123”会变成123,而”011”会变成11(注意:前导的零被忽略了);
    2. 如果字符串中包含有效的浮点格式,如”1.1”,则将其转换为对应的浮点数值(同样,也会忽略前导零);
    3. 如果字符串中包含有效的十六进制格式,例如”0xf”,则将其转换为相同大小的十进制整
      数值;
    4. 如果字符串是空的(不包含任何字符),则将其转换为0;
    5. 如果字符串中包含除上述格式之外的字符,则将其转换为NaN。
    6. 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。
      (注:valueOf() 方法可返回 Boolean 对象的原始值)
var num1 = Number("Hello world!"); //NaNvar num2 = Number(""); //0var num3 = Number("000011"); //11var num4 = Number(true); //1

在处理整数的时候更常用的是parseInt()函数,如果第一个字符不是数字字符或者负号,parseInt()就会返回NaN;也就是说,用parseInt()转换空字符串会返回NaN(Number()对空字符返回0)。
如果第一个字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。当然也可以转化八进制和十六进制.

var num1 = parseInt("1234blue"); // 1234var num2 = parseInt(""); // NaNvar num3 = parseInt("0xA"); // 10(十六进制数)var num4 = parseInt(22.5); // 22var num5 = parseInt("070"); // 56(八进制数)var num6 = parseInt("70"); // 70(十进制数)var num7 = parseInt("0xf"); // 15(十六进制数)

在ECMAScript 5 JavaScript 引擎中,parseInt()已经不具有解析八进制值的能力,”070”被当成八进制字面量,因此转换后的值是十进制的56.
为了消除在使用parseInt()函数时可能导致的上述困惑,可以为这个函数提供第二个参数:转换时使用的基数(即多少进制)

var num1 = parseInt("10", 2); //2 (按二进制解析)var num2 = parseInt("10", 8); //8 (按八进制解析)var num3 = parseInt("10", 10); //10 (按十进制解析)var num4 = parseInt("10", 16); //16 (按十六进制解析)

parseFloat()也是从第一个字符(位置0)开始解析每个字符,始终都会忽略前导的0.

String类型

String 类型用于表示由零或多个16 位Unicode 字符组成的字符序列,字符串可以由双引号(”)或单引号(’)表示.

var firstName = 'Nicholas"; // 语法错误(左右引号必须匹配)
  • 字符字面量
    String 数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其
    他用途的字符。这些字符字面量如下表所示:
    \n 换行
    \t 制表
    \b 空格
    \r 回车
    \f 进纸
    \ 斜杠
    \’ 单引号(’)
    \” 双引号(”)
    \xnn 以十六进制代码nn表示的一个字符(其中n为0~F)
    \unnnn 以十六进制代码nnnn表示的一个Unicode字符(其中n为0~F)
  • 字符串的特点
  • ECMAScript 中的字符串是不可变的,也就是说,字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量.
var lang = "Java";lang = lang + "Script";

3 . 转换为字符串
数值、布尔值、对象和字符串值都有toString()方法,,在调用数值的toString()方法时,可以传递一个参数:输出数值的基数。

var num = 10;alert(num.toString()); // "10"alert(num.toString(2)); // "1010"alert(num.toString(8)); // "12"alert(num.toString(10)); // "10"alert(num.toString(16)); // "a"

Object类型

ECMAScript 中的对象其实就是一组数据和功能的集合,Object 类型所具有的任何属性和方法也同样存在于更具体的对象中。
Object 的每个实例都具有下列属性和方法:
- constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是Object()。
- hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例如:o.hasOwnProperty(“name”))。
- isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型(第5 章将讨论原型)。
- propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in 语句来枚举。与hasOwnProperty()方法一样,作为参数的属性名必须以字符串形式指定。
- toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
- toString():返回对象的字符串表示。
- valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。


操作符号

CMA-262 描述了一组用于操作数据值的操作符,包括算术操作符(如加号和减号)、位操作符、关系操作符和相等操作符

一元操作符

  1. 递增和递减操作符
    ++ - -
    前置型和后置型,后置递增和递减与前置递增和递减有一个非常重要的区别,即递增和递减操作是在包含它们的语句被求值之后才执行的.
var num1 = 2;var num2 = 20;var num3 = --num1 + num2; // 等于21var num4 = num1 + num2; // 等于21var num1 = 2;var num2 = 20;var num3 = num1-- + num2; // 等于22var num4 = num1 + num2; // 等于21

不仅适用于整数,还可以用于字符串、布尔值、浮点数值和对象

s1++; // 值变成数值3s2++; // 值变成NaNb++; // 值变成数值1f--; // 值变成0.10000000000000009(由于浮点舍入错误所致)o--; // 值变成数值-2

2 . 一元加和减操作符
对非数值应用一元加操作符时,该操作符会像Number()转型函数一样对这个值执行转换。换句话说,布尔值false 和true 将被转换为0 和1,字符串值会被按照一组特殊的规则进行解析,而对象是先调用它们的valueOf()和(或)toString()方法,再转换得到的值。

s1 = +s1; // 值变成数值1s2 = +s2; // 值变成数值1.1s3 = +s3; // 值变成NaNb = +b; // 值变成数值0f = +f; // 值未变,仍然是1.1o = +o; // 值变成数值-1

位操作符

位操作符用于在最基本的层次上,ECMAScript 中的所有数
值都以IEEE-754 64 位格式存储,但位操作符并不直接操作64 位的值。而是先将64 位的值转换成32 位的整数,然后执行操作,最后再将结果转换回64 位。

  • 按位非(NOT):|
  • 按位与(AND):&
  • 按位或(OR):^
  • 按位异或(XOR):
  • 左移:(<<)

布尔操作符

  • 逻辑非:(!)逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反
  • 逻辑与(&&)
  • 逻辑或(||)

乘性操作符

  • 乘法 (*)
  • 除法(/)
  • 求模,求余数(%)

加性操作符

  • 加法(+)
  • 减法 (-)

关系操作符

小于(<)、大于(>)、小于等于(<=)和大于等于(>=)

相等操作符

  • 相等比较(==)
  • 不相等 (!=)
  • 全等,类型比较 (=== )
  • 不全等 (!==)
    (null 和undefined 是相等的)

条件操作符

variable = boolean_expression ? true_value : false_value;

赋值操作符

简单的赋值操作符由等于号(=)表示,其作用就是把右侧的值赋给左侧的变量,衍生的复合赋值操作符乘/赋值(*=),除/赋值(/=)等

逗号操作符

使用逗号操作符可以在一条语句中执行多个操作

注:以上操作符在处理时,大多会先转化数据类型才做处理

语句

ECMA-262 规定了一组语句(也称为流控制语句)

  • if语句:条件语句
  • do-while语句:后测试循环语句
  • while语句:前测试循环语句
  • for语句:前测试循环语句
  • for-in语句:精准的迭代语句
  • label语句:在代码中添加标签
  • reak和continue语句:,break 语句会立即退出循环,强制继续执行循环后面的语句。而continue 语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行。
  • with语句:将代码的作用域设置到一个特定的对象中
  • switch语句
switch (expression) {case value: statementbreak;case value: statementbreak;case value: statementbreak;default: statement}

函数

函数对任何语言来说都是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。ECMAScript 中的函数使用function 关键字来声明,后跟一组参数以及函数体。

function functionName(arg0, arg1,...,argN) {statements}

理解参数

ECMAScript 函数不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型.命名的参数只提供便利,但不是必需的。另外,在命名参数方面,其他语言可能需要事先创建一个函数签名,而将来的调用必须与该签名一致。但在ECMAScript 中,没有这些条条框框,解析器不会验证命名参数

没有重载

ECMAScript 函数不能像传统意义上那样实现重载

function addSomeNumber(num){return num + 100;}function addSomeNumber(num) {return num + 200;}var result = addSomeNumber(100); //300

小结

ECMAScript 中的基本数据类型包括Undefined、Null、Boolean、Number 和String。
- 与其他语言不同,ECMScript 没有为整数和浮点数值分别定义不同的数据类型,Number 类型可
用于表示所有数值。
- ECMAScript 中也有一种复杂的数据类型,即Object 类型,该类型是这门语言中所有对象的基础类型。
- 严格模式为这门语言中容易出错的地方施加了限制。
- ECMAScript 提供了很多与C 及其他类C 语言中相同的基本操作符,包括算术操作符、布尔操作符、关系操作符、相等操作符及赋值操作符等。
- ECMAScript 从其他语言中借鉴了很多流控制语句,例如if 语句、for 语句和switch 语句等。ECMAScript 中的函数与其他语言中的函数有诸多不同之处。
- 无须指定函数的返回值,因为任何ECMAScript 函数都可以在任何时候返回任何值。
- 实际上,未指定返回值的函数返回的是一个特殊的undefined 值。
- ECMAScript 中也没有函数签名的概念,因为其函数参数是以一个包含零或多个值的数组的形式传递的。
- 可以向ECMAScript 函数传递任意数量的参数,并且可以通过arguments 对象来访问这些参数。
- 由于不存在函数签名的特性,ECMAScript 函数不能重载。

0 0
原创粉丝点击