JavaScript编程全解笔记

来源:互联网 发布:linux 组播编程 编辑:程序博客网 时间:2024/05/08 10:15
JavaScript 简史
年份 事件 1995 年 网景公司开发了 JavaScript 1996 年 微软发布了和 JavaScript 兼容的 JScript 1997 年 ECMAScript 第 1 版(ECMA-262) 1998 年 ECMAScript 第 2 版 1998 年 DOM Level1 的制定 1998 年 新型语言 DHTML 登场 1999 年 ECMAScript 第 3 版 2000 年 DOM Level2 的制定 2002 年 ISO/ IEC 16262:2002 的确立 2004 年 DOM Level3 的制定 2005 年 新型语言 AJAX 登场 2009 年 ECMAScript 第 5 版 2009 年 新型语言 HTML5 登场

ECMAScript 第 4 版中甚至有引入“类”的概念这样大胆的标 准变更计划。然而,2008 年的标准化工作大会放弃了大幅度变更标准的计划,转为在第 3 版的基础上进 行渐进式改进。

影响客户端 JavaScript 可移植性的原因主要有两点。

1.JavaScript 语言实现方式的不同
2.渲染引擎的差别(DOM 或是 CSS 的解释不同)
现在大多数有名的 JavaScript 实现都基于 ECMAScript 标准,所以只要书写符合 ECMAScript 标准的代码,就能够在很大程度上提高可
移植性。
Acid 并不像 ECMAScript 那样有明确标准,它会对浏览器进行特定测试,根据返回的结果是否相同 来判断代码的执行情况。该测试可以用于判断 JavaScript、DOM、CSS 等各种客户端 JavaScript 的执行情 况。现在很多的浏览器都以符合 Acid 标准(即可以通过 Acid 测试)为目标。 。所幸非 PC 设备的渲染引擎基本上被 WebKit 所垄断,总算使问题稍有缓解。

特点:

1.解释型语言

2.类似于 C 和 Java 的语法结构

3.动态语言:变量和函数是不指定值的类型

4.基于原型的面向对象

5.字面量的表现能力

6.函数式编程

变量基础

如果要读取没有被声明的变量(即作为右值使用该变量),就会引发 ReferenceError 异常;如果将其 作为左值使用,即作为赋值对象使用,则不会发生错误。

常量: const FOO = 7;

1.类的属性 相当于 Java 中的 static 方法或是 static 域

2.prototype 对象的属性 相当于 Java 中的实例方法

3.实例属性 相当于 Java 中的实例域

数据类型

1.字符串型:JavaScript 的字符串型是不可变类型,所以字符 串值本质上是不能改变的。

js> var sobj1 = new String('abc');js> var sobj2 = new String('abc');js> sobj1 == sobj2; // 虽然字符串的内容相同,但是并非引用了同一个对象,所以结果是 falsefalsejs> sobj1 === sobj2; // 虽然字符串的内容相同,但是并非引用了同一个对象,所以结果是 falsefalsejs> var sobj = new String('abc');js> var s = 'abc';js> sobj == s; // 进行数据类型转换的等值运算的结果为 truetrue;js> sobj === s; // 不进行数据类型转换的等值运算的结果为 falsefalse

2.数值型:64 位的浮点小数

3.布尔型

4.null 型

5.undefined 型

\x41 表示“A”

\u03a3 表示希腊字符 Σ

String要防止混用字符串值和字符串对象是很简单的,只要不显式地使用 new String() 即可。调用 String 函数就可以生成字符串值,Number函数显示转换成数值型。Boolean 函数可以将任意值显式地转换为布尔值。

Number即使是这样简单的运算,也无法获得正确的结果。NaN 不但不与其他任何数值相等,就算是两个 NaN 的等值判 断,其结果也为假。预定义全局函数 isFinite 可以对 3 个特殊数值(即 NaN 与正负无穷大)之外的数值进行判断。

undefined,null 型没有与之相对应的 类。

+ 运算符的操作数中如果含有字符串,则会作为字符串连接运算符使用。

Object 类型在被转换为 布尔型之后结果必定为 true。

语句、表达式和运算符

switch 语句会把其在 switch 之后的括号内的表达式,与 case 标签中所写的各个表达式,依次通过相 等运算符(===)进行比较。

无法 delete 通过原型继承而得到的属性

试过程将会在含有 debugger 语句的代码行中断

for in 语句也会枚举通过原型继承得到的属性 枚举属性无序

和 for in 不同,for each in 语句并不是把属性名赋值给变量,而是将属性值赋值给它。

// 使用标签来同时跳出嵌套的循环 outer_loop: while (true) {      print("outer loop");      while (true) {          print("inner loop");          break outer_loop;      } }

三目运算符是右结合的。

两者都是对象引用的情况下,如果引用的是同一个对象则结果为真,否则结果为假。
相等运算符:除字符串和引用比较外都转换除数值再比较!
比较运算符: 一方为字符串值,另一方为可以被转换为字符串值的数据类型的情况,将其转换为字符串值后再对字符串
值进行大小比较

void 是 undefined 类型的单目运算符。无论向其传递什么操作数,其运算结果都会是 undefined 值。
通过 var 声明的全局变量是无法被 delete 的,而没用使用 var 声明的隐式的全局变量则可以被 delete。通过原型继承而得到的属性无法被 delete。

逗号运算符的运 算结果是其右操作数的值。

变量与对象

在 JavaScript 中,赋值运算总是会把右侧的值复制给左侧。对于引用类型的变量来说也是一样,会将 引用(用于指示对象的一种值)赋值给左侧。

判断a是否已经声明if( ‘a’ in this )
new 对象缺点:
● 由于所有的实例都是复制了同一个方法所定义的实体,所以效率(内存效率与执行效率)低下。
● 无法对属性值进行访问控制(private 或 public 等)。
只能使用中括号运算符的情况分为以下几种。

1.使用了不能作为标识符的属性名的情况。

2.将变量的值作为属性名使用的情况。

3.将表达式的求值结果作为属性名使用的情况。

通过 in 运算符检测关联数组的键是否存在,就会发生与原型继承而来的属性相关的问题,enumerable 属性控制是否被枚举。因此,通过 hasOwnProperty 来对其进行检测,是一种更安全的做法。

实现不可变对象的方式
方法名 属性新增 属性删除 属性值变更 确认方法 preventExtensions X O O Object.isExtensible seal X X O Object.isSealed freeze X X X Object.isFrozen
var obj = { x:2, y:3 };Object.preventExtensions(obj); obj.z = 4; Object.keys(obj);//["x", "y"]

一旦更改就无法还原。

如果想让原型继承中的被继承方也不可变化,需要对其进行显式的操作。

函数的调用方式 this 引用的引用对象 构造函数调用 所生成的对象 方法调用 接收方对象 apply 或是 call 调用 由 apply 或 call 的参数指定的对象 其他方式的调用 全局对象

对 Function 对象 f 使用 apply 或 call 方法,就能够调用该函数。不考虑函数内的 this 引用的话,这和 f()
的用法是一样的。两者的区别在于被调用的函数(方法)内的 this 引用,this 引用的是作为 apply/call 的第一
个参数被传递的对象。而 apply 与 call 之间的不同之处在于两者对其他参数的传递方式。对于 apply 来说,剩
余的参数将通过数组来传递,而 call 是直接按原样传递形参。
Object.create方法

js> var obj = { x:2, y:3 }; 与下面的代码等价 js> var obj = Object.create(Object.prototype, { x: {value:2, writable:true, enumerable:true, configurable:true}, y: {value:3, writable:true, enumerable:true, configurable:true} });
方法 说明 defineProperty(o, p, attributes) 向对象 o 增加 更新具有特定信息的属性 p defineProperties(o, properties) 向对象 o 增加 更新具有特定信息的属性 getOwnPropertyDescriptor(o, p) 返回对象 o 的直接属性 p 的信息(值与属性)
函数与闭包

JavaScript 自带有 let 这一增强功能,可以实现块级作用域的效果。可以通过 let 定义(let 声明)、let 语句,以及 let 表达式三种方式来使用 let 功能。语法类似for。

 //计时器实例:var counter=(function counter_class(init) {    // 初始值可以通过参数设定    var cnt = init || 0;    // 设置默认参数的习惯做法(参见 5.5 节)    // 如有必要,可在此声明私有变量与私有函数    return {        // 公有方法        show:function() { print(cnt); },        up:function() { cnt++; return this; }, // return this 在使用方法链时很方便        down:function() { cnt--; return this; }    };})();

在调用 apply 与 call 时将会立即调用目标函数,而在调用 bind 时则不会如此,而是会返回一个函数(闭包)。

事件

如果要中止其他的事件侦听器的执行,则需要使用在 DOM Level 3 中引入的stopImmediatePropagation() 方
法。与 stopPropagation() 方法不同,当前侦听器目标中设定的其他事件侦听器的执行也会被中止。

var btn = document.getElementById('foo');    function sayFoo(event) {    alert('foo');    event.stopPropagation();}function sayBar(event) {    alert('bar');    event.stopImmediatePropagation();}function sayBaz(event) {    alert('baz');}btn.addEventListener('click', sayFoo, false);btn.addEventListener('click', sayBar, false);btn.addEventListener('click', sayBaz, false);// 在点击按键之后,将会显示 foo 与 bar 的对话框,baz 的对话框不会被显示
jQuery

在使用 live() 时,其实事件侦听器是被设定于 document 对象之上。而如果使用的是delegate() 方法,则能够对 document 对象之外的对象执行 live() 以设定事件侦听器。这是因为 live() 在 $(‘.foo’) 时会查找 foo 类的元素,而 delegate() 则不需要进行这样的查找操作。

0 0
原创粉丝点击