其他分享
首页 > 其他分享> > 作用域

作用域

作者:互联网

变量提升

在代码执行之前,会先进行代码的预解析,将var和function声明的变量进行提升,提升为window的属性(全局变量),并将var声明的变量赋值为undefined,var的提升在function之前

console.log(num);
say();
var num = 100;
function say(){
	console.log('hello');
}

console.log(num);
say();

变量提升

var num;
function say(){
	consloe.log('hello');
}
console.log(num);//undefined 
say();//'hello'
num = 100;

console.log(num);//100
say();//'hello'

变量名一致时会进行覆盖

console.log(num);
var num = 100;
console.log(num);
function num(){
	console.log('20');
}
console.log(num);
var num = 50;
console.log(num);

变量提升

var num;
function num(){//覆盖原来的,此时num为一个函数
	console.log('20');
}
console.log(num);//f num(){	console.log('20');}
num = 100;
console.log(num);//100
console.log(num);//100
num = 50;
console.log(num);//50

全局作用域

全局作用域是最大的作用域,指向window对象,在全局作用域内声明的变量,在JS代码的时时处处都可以访问

  1. 全局作用域是最外围的一个执行环境,在web浏览器中,全局执行环境被认为是window对象。
  2. 所有全局变量和函数都是作为window对象的属性和方法创建的。
  3. 全局变量拥有全局作用域,在javascript代码中的任何地方都是有定义的。
  4. 全局作用域直到应用程序退出例如关闭网页或浏览器时才会被销毁
var num = 13;
function fn(){
	console.log(num);
}
fn();//打印13

局部作用域

特点:函数作用域中的所有代码执行完毕后,该作用域被销毁,保存在其中的所有变量和函数定义也随之销毁。

function test(){
    var message  = 'hi';
}
test();
alert(message); // 报错

作用域链

  1. 全局作用域变量包括:全局变量(直接声明在全局中不在任何函数体中)成为window的属性、不使用var声明而直接赋值的变量
  2. 全局作用域直到应用程序退出例如关闭网页或浏览器时才会被销毁
  3. 局部变量:函数参数、函数内使用var声明的变量
  4. 函数调用产生局部作用域,函数调用完毕局部作用域销毁,保存在其中的所有变量和函数定义也随之销毁
  5. 内部作用域可访问外部作用域、外部作用域不可访问内部
  6. 函数局部作用域有与全局同名的变量,函数内部访问时,优先访问内部的

this

非严格模式下:

  1. 全局作用域中,this 指向window
  2. 函数里的this 指向函数的调用者 找不到调用者 就指向window对象
  3. 构造函数里的this 指向构造函数创建的对象实例

严格模式下:

  1. 全局作用域中,this指向window对象(与非严格模式一样)
  2. 全局作用域中函数中的this,指向undefined
  3. 对象的函数中的this指向调用函数的对象实例(与非严格模式一样)
  4. 构造函数中的this指向构造函数创建的对象实例(与非严格模式一样)

对象

对象的this指向该对象

function fm() {
	console.log( this.a );
}
var obj = {
	a: 2,
	fn: fm
};
obj.fn(); //2

函数

函数的this指向调用者,对象调用指向对象,没有调用指向window

function fm() {
	console.log( this.a );
}
var obj = {
	a: 2,
	fn: fm
};
obj.fn(); //2
fn();//undefined

改变this指向

call

fn.call(obj, param1,...) 隐式帮我们调用函数
参数:
obj fn内部的this指向的对象
从第二个参数开始,都是传递给fn函数的实参

var a = 89;
var obj = { a: 999 };
function fn(a, b) {
	console.log(this.a);
	return a + b;
}
var res1 = fn(100, 300);
var res2 = fn.call(obj, 100, 300);
console.log(res1 == res2);

apply

fn.apply(obj, [param1,param2...]) 隐式帮我们调用函数
参数:
obj fn内部的this指向的对象
第二个参数是一个数组,数组的每一个元素都会被当作实参传递给fn

var a = 89;
var obj = { a: 999 };
function fn(a, b) {
	console.log(this.a);
	return a + b;
}
var res3 = fn.apply(obj, [100, 300]); // fn(100, 300)
console.log(res3); // 400

bind

fn.bind(obj, param1,...) 不会隐式帮我们调用函数 返回一个函数的引用地址
参数:
obj fn内部的this指向的对象
从第二个参数开始,都是传递给fn函数的实参
注意:如果想bind的同时调用函数 就要()在后面表示函数的调用

var a = 89;
var obj = { a: 999 };
function fn(a, b) {
	console.log(this.a);
	return a + b;
}
var res4 = fn.bind(obj, 100, 300);
console.log(res4()); // 400

var res5 = fn.bind(obj, 100, 300)();
console.log(res5); // 400

var res6 = fn.bind(obj)(100, 300);
console.log(res6); // 400

区别

执行

返回值:

标签:console,log,作用域,num,var,fn
来源: https://www.cnblogs.com/Kongqingzhi/p/16608456.html