对象中包含什么:
JavaScript中的大多数对象可以分为如下两种类型:
Function对象,例如alert()函数,可以使用参数来改变这类对象的功能。
Object对象,这类对象不能像函数那样被调用,而且具有固定的功能-除非它们包含额外的Function对象
为了提高效率,JavaScript也提供了下列内置对象:
1、Object是通用基础对象,可以使用它来创建简单的静态对象
2、Function是被所有使用参数的对象复制的对象,也是在脚本中定义函数时所创建的对象
3、Array是一种特殊的属性和方法的集合,比如使用其length属性可以通过循环迭代操纵这类对象也可以使用方括号
4、String、Boolean和Number则分别用于表示字符串、布尔值以及数字所有内置对象都可以通过new关键字或者其它特殊语法来创建,花括号({})是Object的简写形式,而方括号(【】)则是Array的简写形式。
Window对象中的一切
alert(message);
}
如果上面的函数是在JavaScript文件最顶层编写的没有被其它对象包含的代码,那么:
myFunction('without window ojbect');
window.myFunction('with window object');
这两种调用方法结果是相同的,但是如果是在另一个对象中创建的这个函数,由于作用域链的关系,情况会变得复杂一些
function override(){
//覆盖alert函数
var alert = function(message){
window.alert('overridden:' + message);
}
alert('alert');
//在override()函数的作用域中调用原始的alert()函数
window.alert('window.alert');
}
//在window的作用域中调用原始的alert()函数
alert('alert from outside');
在页面载入完成后,会有三个警告提示:"overridden:alert"、"window.alert"、"alert from outside",当然,如果在脚本文件最顶层如下写:
window.alert('overridden:' + message);
}
alert('test');
那么脚本会因为过渡递归而终止运行。因为这次是在脚本的最顶层覆盖的alert()方法,相当于你自己的方法替换了window.alert()方法。
创建你自己的对象
//创建构造函数
function myConstructor(message){
alert(message);
this.myMessage = message;
//私有属性
//私有方法
function alertMessage() {
alert(myOwner.myMessage);
}
//在实例化时显示信息
alertMessage();
//特权方法(也是公有方法)
this.myMessage =
alertMessage();
}
}
//静态属性
//静态方法
alert(this.name);
}
//添加一个公有方法
this.myMessage += ' ' + string;
//这是错误的
this.myMessage +=
}
在新实例上调用clearMessage将得到预期的效果
var myObject = new myConstructor('hello world');
myObject.clearMessage();
myObject.appendToMessage(); //特权方法也是公有方法
你可能已经注意到了,这个例子代码中也包含另外一个私有属性myOwner,它引用的是this。通过将this赋值给myOwner,你的私有方法就可以通过引用myOwner来访问myConstructor的实例。私有方法是存在于构造函数作用域中的自包含对象,它们实际上并不是prototype的方法,因此在私有方法内部this引用的只是私有方法的实例,而非myConstructor的实例。由于这些私有成员被严格限制在了构造函数的作用域中,因此也不能通过对象自己的公有方法来访问它们。要避免这一限制,可以使用特权方法
var myObject = {
propertyA: 'value',
propertyB: 'value',
methodA:function(){},
methodB:function(){}
}
上面的代码跟下面的代码是等效的:
var myObject = new object();
myObject.propertyA = 'value';
myObject.proertyB = 'value';
myObject.methodA = function(){};
myObject.methodB = function(){};
也是就是,下面的简写形式是等效的:
var myObject = {}; var myObject = new object();
也可以使用对象字面量语法向prototype属性中添加所有仅有成员
myConstructor.prototype = {
propertyA:'value',
propertyB: 'value',
methodA:function(){},
methodB:function(){}
}
通过Call()和apply()重新定义执行环境
function doubleCheck(){
this.message = 'are you sure you want to leave?';
}
doubleCheck.prototype.sayGoodby = function() {
return confirm(this.message);
}
function initPage(){
var clickedLink = new doubleCheck();
var links = document.getElementsBytagName('a');
for(var i = 0; i < links.length; i++){
links
}
}
这个例子中载入事件的预期效果是遍历页面中的所有链接,然后clickedLink.sayBoodby执行链接的click事件。但是由于this引用的对象会随着环境而改变,当例子中的sayGoodby()方法在<a>这个HTML元素的环境中执行时,this所引用的就是这个HTML元素,而不是你所期望的clickedLink对象,解决这个问题的方法就是使用Function对象的call()或apply()方法,用以改变函数的执行环境
clickedLink.sayGoodby.call(window)或者clickedLink.sayGoodby.apply(window);
如果sayGoodby带有参数可以使用下面方法:
clickedLink.sayGoodby.call(window,argument1,argument2,...);
clickedLink.sayGoodby.apply(window,arguments);
对于apply,应该将方法的参数做为数组放在第二个参数位置传递,这是它们的唯一区别
function bindFunction(obj,func){
return function(){
func.apply(obj,arguments);
}
}
以上代码的关键在于,由bindFunction返回的匿名函数使用内部作用域中特殊的arguments参数,作为以外部作用域中的obj和func调用apply()时传递的额外参数,执行以上方法主要是为了给原始函数创建一个新环境。