阅读 566

js高级程序设计 - 温故而知新

文章来源:www.bookcss.com/note/12/33

JavaScript 诞生于 1995 年。当时,它的主要目的是处理以前由服务器端语言(如 Perl)负责的一些输入验证操作。在 JavaScript 问世之前,必须把表单数据发送到服务器端才能确定用户是否 没有填写某个必填域,那你可能九年级木块模块了是否输入了无效的值。 Netscape Navigator 希望通过 JavaScript 来解决这个问题。 在人们普遍使用电话拔号上网的年代,能够在客户端完成一些基本的验证任务绝对是令人兴奋的。毕竟,拨号上网的速度之慢,导致了与服务器的每一次数据交换事实上都成了对人们耐心的一次考验。

1.一个完整的 JavaScript 实现应该由下列三个不同的部分组成:

  • 核心(ECMAScript)
  • 文档对象模型(DOM)
  • 浏览器对象模型(BOM)

2.script元素:

script元素定义了下列 6 个属性:

  • async :可选。表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或 等待加载其他脚本。只对外部脚本文件有效。
  • charset :可选。表示通过 src 属性指定的代码的字符集。由于大多数浏览器会忽略它的值, 因此这个属性很少有人用。
  • defer:可选。表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有 效。IE7 及更早版本对嵌入脚本也支持这个属性。
  • language:已废弃。
  • src:可选
  • type:可选。

3.ECMAScript中的基本数据类型

基本数据类型:Undefined、Null、Boolean、Number 和 String。

4.基本数据和引用类型的值

  • 基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;
  • 从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本;
  • 引用类型的值是对象,保存在堆内存中;
  • 包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针;
  • 从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象

5.引用类型

  • Object类型
  • Array类型
  • Date类型
  • RegExp类型
  • Function类型

函数内部属性

  • arguments.callee:返回一个对函数的引用,该函数调用了当前函数。
function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num - 1)
    }
}

复制代码
  • arguments.callee.caller:返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文。
function outer(){ 
 inner(); 
} 
function inner(){ 
 alert(arguments.callee.caller); 
} 
outer(); 
复制代码

6.垃圾收集

javascript含有自动垃圾收集机制。

垃圾收集的方法:

  • JavaScript 中最常用的垃圾收集方式是标记清除。

当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

  • 另一种不太常见的垃圾收集策略叫做引用计数。

引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是 1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减1。当这个值的引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存

var element = document.getElementById("some_element"); 
var myObject = new Object(); 
myObject.element = element; 
element.someObject = myObject; 
复制代码

这个例子在一个 DOM 元素(element)与一个原生 JavaScript 对象(myObject)之间创建了循环 引用。其中,变量 myObject 有一个名为 element 的属性指向 element 对象;而变量 element 也有 一个属性名叫 someObject 回指 myObject。由于存在这个循环引用,即使将例子中的 DOM 从页面中 移除,它也永远不会被回收。

为了避免类似这样的循环引用问题,最好是在不使用它们的时候手工断开原生 JavaScript 对象与DOM 元素之间的连接。例如,可以使用下面的代码消除前面例子创建的循环引用:

myObject.element = null; 
element.someObject = null; 
复制代码

7.subString、substr、slice之间的区别

  • stringObject.substring(start,stop)
  • stringObject.substr(start,length)
  • arrayObject.slice(start,end)

8.对象属性类型

ECMAScript 中有两种属性:数据属性和访问器属性。

  • 数据属性 Configurable:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特 性,或者能否把属性修改为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的 这个特性默认值为 true。 Enumerable:表示能否通过 for-in 循环返回属性。像前面例子中那样直接在对象上定 义的属性,它们的这个特性默认值为 true。 Writable:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的 这个特性默认值为 true。 Value:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候, 把新值保存在这个位置。这个特性的默认值为 undefined。

  • 访问属性 Configurable:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特 性,或者能否把属性修改为数据属性。对于直接在对象上定义的属性,这个特性的默认值为 true。 Enumerable:表示能否通过 for-in 循环返回属性。对于直接在对象上定义的属性,这 个特性的默认值为 true。 Get:在读取属性时调用的函数。默认值为 undefined。 Set:在写入属性时调用的函数。默认值为 undefined。

      使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化
    复制代码

9.创建对象的几种模式

  • 工厂模式
function person(name,age){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.sayName = function(){
        console.log(this.name)
    }
    return o;
}

var p = person('张三',20);
p.sayName(); // 张三
复制代码
  • 构造函数模式
function Person(name,age){
    this.name = name;
    this.age = age;
    this.sayName = function(){
        console.log(this.name);
    }
}

var p = new Person('张三',20);
p.sayName(); // 张三
复制代码

New实例化对象会经历以下4个步骤:

1. 创建新对象
2. 将构造函数的作用域复制给新对象
3. 执行构造函数的方法
4. 返回新对象
复制代码
  • 原型模式
function Person() {}
Person.prototype = {
    constructor: Person,
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
    friends: ["Shelby", "Court"],
    sayName: function() {
        alert(this.name);
    }
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Court,Van" 
alert(person2.friends); //"Shelby,Court,Van" 
alert(person1.friends === person2.friends); //true

复制代码
  • 组合构造函数模式和原型模式
function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function(){
    console.log(this.name)
};

var p = new Person('张三',10);
p.sayName(); // 张三
复制代码
  • 动态原型模式
function Person(name,age){
    this.name = name;
    this.age = age;
    
    if (typeof this.sayName != 'function') {
        Person.prototype.sayName = function(){
            console.log(this.name)
        };
    }
}

var p = new Person('张三',10);
p.sayName(); // 张三
复制代码
  • 寄生构造函数模式
function Person(name,age){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.sayName = function(){
        console.log(this.name)
    };
    return o;
}

var p = new Person('张三',10);
p.sayName(); // 张三
复制代码
  • 稳妥构造函数模式
function Person(name,age){
    var o = new Object();
    o.name = name;
    o.age = age;

    o.sayName = function(){
        console.log(name)
    };
    return o;
}

var p = Person('张三',10);
p.sayName(); // 张三
复制代码

跨域请求技术

  • CORS(Cross-Origin Resource Sharing,跨源资源共享)
  • 图片Ping 最常用于跟踪用户点击页面或动态广告曝光次数
  • JSONP JSONP 是通过动态script元素(要了解详细信息,请参考第 13 章)来使用的,使用时可以为 src 属性指定一个跨域 URL。这里的script元素与元素类似,都有能力不受限制地从其他域 加载资源。因为 JSONP 是有效的 JavaScript 代码,所以在请求完成后,即在 JSONP 响应加载到页面中 以后,就会立即执行。来看一个例子
function handleResponse(response){ 
 alert("You’re at IP address " + response.ip + ", which is in " + 
 response.city + ", " + response.region_name); 
} 
var script = document.createElement("script"); 
script.src = "http://freegeoip.net/json/?callback=handleResponse"; 
document.body.insertBefore(script, document.body.firstChild); 

复制代码
  • Comet
  • SSE(Server-Sent Events,服务器发送事件)
  • Web Sockets

对象防篡改

  • Object.preventExtensions():不可添加属性和方法
  • Object.seal():不能删除属性和方法
  • Object.freeze():不可添加属性和方法并且不能删除属性和方法

性能优化

  • 避免全局查找
  • 避免 with 语句
  • 避免不必要的属性查找

使用变量和数组要比访问对象上的属性更有效率

  • 避免双重解释
//某些代码求值——避免!! 
eval("alert('Hello world!')"); 

//创建新函数——避免!! 
var sayHi = new Function("alert('Hello world!')"); 

//设置超时——避免!! 
setTimeout("alert('Hello world!')", 500); 

//已修正
alert('Hello world!'); 

//创建新函数——已修正
var sayHi = function(){ 
 alert('Hello world!'); 
}; 

//设置一个超时——已修正 
setTimeout(function(){ 
 alert('Hello world!'); 
}, 500); 
复制代码
  • 最小语句数
//一个语句 
var count = 5, 
    color = "blue", 
    values = [1,2,3], 
    now = new Date(); 

//只用一条语句创建和初始化数组 
var values = [123, 456, 789]; 

//只用一条语句创建和初始化对象 
var person = { 
    name : "Nicholas", 
    age : 29, 
    sayName : function(){ 
       alert(this.name); 
    } 
}; 
复制代码
  • 优化循环

推荐个开发专用的笔记吧,我已经习惯在这写文档笔记了。Hbook笔记

关注下面的标签,发现更多相似文章
评论