1、作用域概念:作用域是可访问变量的集合。
局部作用域 : 变量在函数内声明,变量为局部作用域。只能在函数内部访问。
全局作用域:变量在函数外定义,即为全局变量。网页中所有脚本和函数均可使用。
没有使用 var 关键字,该变量为全局变量。
局部变量在函数执行完毕后销毁。
全局变量在页面关闭后销毁。
函数参数只在函数内起作用,是局部变量。
在 HTML 中, 全局变量是 window 对象: 所有数据变量都属于 window 对象。
var name="one";
function test(){
var name="two";
var test1=function (){
var name="three";
console.log(name); //three
}
function test2(){
console.log(name); // two
}
test1();
test2();
}
test();
console.log(name) //one
-------------------------------------------------------------
if (true) {
//在块中定义了一个变量,它的作用域链的第一个对象就是全局对象window
var tmp = 0;
}
alert(tmp); //0
--------------------------------------------
var a=12;
var b=2;
function hello(){
var b="hello";
console.log(a,b); //12 , "hello"
}
hello();
console.log(a,b); // 12 2
---------------------------------------------------
var t = "bb";
function test() {
//执行t的时候,它会先找作用域链对象,由于它定义在函数内部,所以这个函数就是它的作用域链的第一个对象
//而在这个对象里又有t的定义,所以t就是局部变量了,它替换了全局变量t
//t只是此时有定义,但并没有赋值,赋值在下一行,所以这里输出了undefined
alert(t); //undefined
var t = "aa";
alert(t); //aa
}
test();
2、this作用域 :当做函数调用,无论在什么时候都是window。
setTimeout中匿名函数的作用域是:window,无论在什么时候。
函数在被调用的时候会意外接受两个参数:this和argument,其中this的值跟取决于函数的调用模式:
1,方法调用模式 o.a() //this指的o
2,函数调用模式 a() //this指的windows
3,构造器调用模式 new a() //this为a的实例对象
4,apply(call)的间接调用模式 a.apply(xx,[yy]) //this指的xx
var i = 0;
var o = {
i: 1,
fn1: function(){
this.i = 10; //this---o
function m1(){
alert(this.i); //this---window this.i---0
this.i = 100; //this---window
}
m1();
},
fn2: function(){
this.i = 10; //this---o
var m2=function(){
alert(this.i); //this---window this.i---0
this.i = 100; //this---window
}
},
}
o.fn1();
0.fn2();
------------------------------------------------------
在函数内部,this指向window
var name = "global this";
function globalTest() {
this.name = "rename global this"; //this指向了window,应为函数在全局环境中
console.log(this.name);
}
globalTest(); // rename global this
总结:对于全局的方法调用,this指向的是全局对象window。
-------------------------------------------------
var name = "global name";
function showName() {
this.name = "showName function";
}
var obj = new showName();
console.log(obj.name); //showName function this---obj对象
console.log(name); //global name this是windwo对象
--------------------------------------------------------------------------------------
var name="aaa";
function showName() {
console.log(this.name);
}
var obj = {};
obj.name = "ooo";
obj.show = showName;
obj.show(); //ooo
console.log(name); //”aaa“
------------------------------------------------
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name; //this指向window
};
}
};
alert(object.getNameFunc()()); //The Window
3、apply 、call调用时的this:apply和call都是为了改变函数体内部的this指向。以扩充函数赖以运行的作用域。
语法:call(thisObj,Object)
apply(thisObj,[argArray])
// 例 1
window.color = 'red';
document.color = 'yellow';
var s1 = {color: 'blue' };
function changeColor(){
console.log(this.color);
}
changeColor.call(); //red (默认传递参数)
changeColor.call(window); //red
changeColor.call(document); //yellow
changeColor.call(this); //red
changeColor.call(s1); //blue
// 例 2
var Pet = {
words : '...',
speak : function (say) {
console.log(say + ''+ this.words)
}
}
Pet.speak('Speak'); // 结果:Speak...
var Dog = {
words:'Wang'
}
// 将this的指向改变成了Dog
Pet.speak.call(Dog, 'Speak'); // 结果: SpeakWang
apply方法差不多
// 例 1
window.number = 'one';
document.number = 'two';
var s1 = {number: 'three' };
function changeColor(){
console.log(this.number);
}
changeColor.apply(); // one (默认传参)
changeColor.apply(window); // one
changeColor.apply(document); // two
changeColor.apply(this); // one
changeColor.apply(s1); // three
// 例 2
function Pet(words){
this.words = words;
this.speak = function () {
console.log( this.words)
}
}
function Dog(words){
// Pet.call(this, words); // 结果: Wang
Pet.apply(this, arguments); // 结果: Wang
}
var dog = new Dog('Wang');
dog.speak();
call与apply不同点。传递参数方式不同
function add(c,d){
return this.a + this.b + c + d;
}
var s = {a:1, b:2 };
console.log(add.call(s,3,4)); // 1+2+3+4 = 10
console.log(add.apply(s,[5,6])); // 1+2+5+6 = 14