1.javaScript删除某个对象的属性,方法
var bingo1 = {};
bingo1.shouts = 'hey!';
bingo1.hello = function()
{
console.log('hello');
};
//删除bingo1对象的属性shouts
delete bingo1.shouts;
//删除bingo1对象的方法hello,这里不能写成delete bingo1.hello(),它会调用bingo1.hello()
delete bingo1.hello;
bingo1.hello();
console.log(bingo1.shouts);
2.函数分类:一般函数 和 匿名函数
一般函数(有指定函数名doSomethingCool)
function doSomethingCool()
{
console.log('I do something mindblowingly cool');
}
匿名函数(没有指定函数名)
function ()
{
console.log('My parents forgot to name me!');
};
function doSomethingCool()
{
console.log('I do something cool');
}
//现在makeSomeNoise和doSomethingCool两个对象都引用了相同的函数 doSomethingCool()
var makeSomeNoise = doSomethingCool;
//调用doSomethingCool函数,输出的是I do something cool
doSomethingCool();
//分配doSomethingCool函数名(实际也是个对象)指向另一个不同的函数
doSomethingCool = function()
{
console.log('I do something hot');
}
//再次调用doSomethingCool函数,输出则是I do something hot,与上面不同
doSomethingCool();
3函数的调用
// 通常的方式
function boring(msg)
{
console.log( msg);
}
boring('The usual way');
//通常的方式-- 匿名形式
A
(function cool(msg){
console.log( msg);
})('The unusual way - anonymously');
B
var usefulStuff = (function makeUsefulStuff(){
var bingo={desc:'My name is Bingo'};
return bingo;
})();
//这里运用这种调用方式,立即调用makeUsefulStuff()函数返回bingo赋给了usefulStuff
4.构造函数
function Employee()
{
console.log('Employee function');
};
var emp1 = new Employee();
当你调用使用new关键字的函数时,在运行时会创建一个空对象,并将该对象传递到这函数,该对象就变成了在这函数内this的值;
一旦完成其执行的函数,该函数将自动返回一个引用到this,即使你在函数的末尾显式地编写一个返回语句.
注意,如果你的调用的函数没有new关键字,它就没有创建新对象,例如调用 Employee()函数,它就不会返回一个引用到this
而是如果函数有显示地编写返回语句,就返回该语句的内容,因为这里Employee()没有,所以没有返回什么内容.
Object对象的结构如下:
function Employee()
{
console.log('Executing Employee function');
};
var emp1 = new Employee();
var dummy = {};
var hello = new Object();
console.log(dummy.constructor); //a
console.log(hello.constructor); //b
console.log(emp1.constructor); //c
结果输出的是:
Executing Employee function
function Object() { [native code] }
function Object() { [native code] }
function Employee()
{
console.log('Executing Employee function');
}
因为dummy和hello实际都是Object,所以a 和 b实际上调用的都是Object的constructor属性,可以从Object的结构图看出constructor的结构.
而c则输出了自身Employee对象的构造函数来
由于函数本身也是Object(对象),所以函数也应当拥有构造函数,如下:
function Employee()
{
console.log('Executing Employee function');
}
console.log(Employee.constructor);
console.log((function noname(){}).constructor);
console.log(Function.constructor);
结果输出的是:
function Function() { [native code] } function Function() { [native code] } function Function() { [native code] }
这里说明的Employee()函数的构造函数是function Function() { [native code] }
匿名函数的构造函数是function Function() { [native code] }
Function本身的构造函数也是function Function() { [native code] }
this关键字与函数的上下文
function outerFunc()
{
console.log('outer ' + this);
function innerFunc()
{
console.log('inner ' + this);
}
innerFunc();
}
outerFunc();
输出的是如下:
outer [object Window]
inner [object Window]
因为调用outerFunc()没有指定它是属于哪个Object(对象)上,
那么javaScript认为它是属于window对象上的,实际上等价于window.outerFunc().
var bingo = {};
bingo.outerFunc=function()
{
console.log('outer ' + this);
function innerFunc()
{
console.log('inner ' + this);
}
innerFunc();
};
bingo.outerFunc();
结果输出的是:
outer [object Object]
inner [object Window]
由于调用bingo.outerFunc()中,指定了outerFunc()所属的为bingo对象上的,它实际也是个Object,所以outer中输出的this为outer [object Object]
而inner中输出的this则为[object Window] ,这暗示上下文context并没有继承,即当函数A定义在另一个函数B内,并在函数B内调用,在函数A内是没有继承函数B(outer function外部函数)的this
var myHappyObject =
{
name : 'MrHappy',
rename : function (name)
{
this.name = name;
console.log(this.name);
}
};
var duplicateReference = myHappyObject.rename;
myHappyObject.rename('myHappyObject');
console.log(window.name); //a
duplicateReference('window');
console.log(window.name); //b
结果输出的是:
myHappyObject
(空字符串)
window
window
首先执行var duplicateReference = myHappyObject.rename;将duplicateReference引用指向了函数renam即
rename : function (name)
{
this.name = name;
console.log(this.name);
}
由于调用duplicateReference('window');没有给它指定明确的对象,所以javaScript认为它属于window对象,即
调用的是window.duplicateReference('window'),接着它进入rename函数中,执行this.name = name,这时
this指向的正式window,所以它为window对象添加了不必要的属性name,并将它赋值为‘window’值,这一点可以从
输出结果看出,首先执行a时,输出的window.name为‘空字符串’.而最后执行b时则输出了‘window’,可见执行
duplicateReference('window');就是为window对象添加属性name并赋值为‘window’.
5.闭包
function printer(msg)
{
function printMe()
{
console.log(msg);
}
return printMe;
}
var p = printer('first');
var b = printer('second');
p();
b();
结果输出为:
first
second
这里p和b引用的都是相同的函数-printMe,因为它们都调用printer,printer函数最终返回printMe内部函数的引用.
虽然它们引用相同的函数printMe,但是结果输出的却不相同(一般如果引用相同的函数在这里输出会相同),这是为什么?
这是因为虽然外部函数printer()执行完毕,内部函数printMe()仍然保留着外部函数printer()的变量状态的一个隐藏的引用,
在上面,因为msg是外部函数printer()的一个局部变量,而且我们一直保留着内部函数printMe()的引用,
所以外部函数printer()的局部变量msg的生命周期一直保留着,所以输出的是不同的.
如果您可以 保存 内部函数 引用,您可以人为地增加 外部函数的一个局部变量 的生命周期
var holder = {};
holder.outer =function (name)
{
this.name=name;
//保存outer的this到that以便inner可以用
var that = this;
console.log('Outer name : ' + name);
function inner(){
console.log("Inner Name : " + that.name);
};
return inner;
};
var p = holder.outer('Popeye');
p();
输出的结果为:
Outer name : Popeye
Inner Name : Popeye
那么如果你想在inner内部函数内利用outer外部函数的this来实现一些功能的话,
你可以把this封装在一个闭包变量,如上面的var that = this;然后就可以在inner使用that.name
function helloWorld()
{
if(1)
{
var a = 76;
}
console.log(a);
}
helloWorld();
输出的结果为:76
在javaScript中一个变量的作用域范围是在它声明所在的整个函数中,
所以上面虽然是在if中声明var a变量,但是还是能在 helloWorld()函数内if外中访问该变量a
var n = 1;
function someRandomFunction()
{
console.log(n); //输出undefined
var n = 100;
console.log(n); //输出100
}
someRandomFunction();
输出的结果为:
undefined
100
为什么第一个会输出undefined呢?不是在someRandomFunction()函数外已经声明了var n = 1吗?
出现这种奇怪的行为原因是javaScript存在一个功能叫做hoisting(“提升”)
即对于在任何作用域范围内声明的变量、JavaScript会分离变量声明和变量的初始化,
将变量的声明放置到该作用域范围内的第一行,而变量的初始化则还是放置到程序员初始化的位置中.
所以上面的函数等价于
var n = 1;
function someRandomFunction()
{
var n; //变量的声明隐藏在这里
console.log(n); //所以这里输出undefined,因为上一行只是声明变量n,还没初始化
n = 100; //现在变量n被初始化
console.log(n); //这里输出了100
}
someRandomFunction();
//undefined
function someRandomFunction()
{
var n;
console.log(n);
}
//undefined
function someRandomFunction()
{
console.log(n);
var n;
}
函数调用顺序注意
usual();
function usual() //a形式
{
console.log('function defined in usual way')
}
variable();
var variable = function() //b形式
{
console.log('function defined in variable way');
};
结果输出为:
function defined in usual way
Uncaught TypeError: Property 'variable' of object [object Window] is not a function
说明函数定义用通常的形式即a形式,可以在函数定义前就调用它usual();
而b形式的定义方式是不能在函数定义之前就去调用它的,它会报错,因此最好都是在函数定义后再去调用该函数.