js中的作用域和作用域鏈(入門級別)

在js中作用域 有 全局作用域 局部作用域 還有一個es6的 塊級作用域
1.全局作用域 一般定義在 全局中 在任何地方都可以使用

var a=10; 全局作用域
console.log(a); //輸出 10
console.log(window.a); // 輸出 10
function zuoyong(){
	console.log(a)
}
zuoyong(); // 輸出10
{
	console.log(a); // 輸出 10
}

2.局部作用域 一般使我們在函數內部定義的變量 所在的作用域

function fn(){
	var a=10;
	console.log(a);
}
fn();  // 輸出 10
console.log(a); // 全局作用域中並沒有定義a 所以報錯 a is not defined
  1. 塊級作用域則是 es6 新增的 唯有使用 let 和const 關鍵字生效的 這個就不一一贅述了
    我之前的博客 let 和const關鍵字 中有詳細講解
    https://blog.csdn.net/yunchong_zhao/article/details/105894891

作用域鏈
講解這個 就避不開 js的一座大山 閉包的相關知識
面試經常被問到的一個問題就是 你在工作中哪裏會用到閉包
保證this 上下文一致的 使外層函數的this 作用到內層函數。

閉包 作爲菜鳥的我的理解就是 內層函數的 引用外層函數的作用域 導致無法在內存中釋放,這個 作用域就可以叫做閉包 。

很經典的一個例子就是累加器的實現

function sum(){
	var sum=0;
	return function(){
		return ++sum;
	}
}
var fn3=sum();
console.log(fn3());
console.log(fn3());
console.log(fn3());
console.log(fn3());
console.log(fn3());
console.log(fn3());

在這裏插入圖片描述
而上面的這個例子無形之中就已經牽扯出來了作用域鏈了
內層的那個function 裏面是沒有sum 這個變量的 所以它就會沿着作用域鏈 往外層尋找
看見了外層函數 sum 有一個 sum變量 他就引用到了
這裏之所以沒有釋放掉 可以看出後面幾個函數的執行結果是在前面的結果之上進行了加1
和js的垃圾回收機制 有關 1. 標記清楚 2.引用計數

我們再看看一個例子 可能就明白了

var a=10;
function sum(){
	var sum=0;
	return function(){
		console.log(a);
	}
}
var func=sum();
func(); //  輸出 10

這個相當於了三層 內層函數=>外層函數=>全局作用域
這個就是一個作用域鏈 和原型鏈有點類似 在當前作用域中找不到 就沿着作用域鏈往上面找

這裏也附上一個只是點 牽扯作用域 很敏感的一個 關鍵字 就是 this 關鍵字

function func(){
	console.log(this===window)
}
func(); //true  this 一般指向當前的作用域

其中箭頭函數中可沒有this

var obj={
	name:"zhangsan",
	say:function(){
		console.log(this.name)
	}
}
obj.say();  // zhangsan
// 改成箭頭函數  這裏爲什麼不用name 在window中 name好像是一個保留字吧
var obj={
	a:"zhangsan",
	say:()=>{
		console.log(this.a,this==window)
	}
}
obj.say(); // undefined  true

很奇怪是把 this 箭頭函數中的this 最後竟然指向了 window
就是我在上面說了 箭頭函數中沒有 this 作用域 他就會沿着往上面找 自然就找到了 全局中的window 作用域了 主要是這個例子 只是套了兩層 如果三層的話他會指向第二層的this
指向window一般就是一經找到了 作用域鏈的最高層了 不能再往上面走了
在舉一個例子 下面的這個是不加new的

window.name="123";
function Person(name,age){
	this.name=name;
	this.age=age;
	return ()=>{
		console.log(this.name);
	}
}
var app=Person("zhangsan",15);
app(); // zhangsan
var Fn=()=>{
	return function(){
		console.log(this.name)
	}
}
Fn()(); // zhangsan

還有一個是加new的

window.name="123";
function Person(name,age){
	this.name=name;
	this.age=age;
	return ()=>{
		console.log(this.name);
	}
}
var app=new Person("zhangsan",15);
app(); // 輸出 zhangsan
var Fn=()=>{
	return function(){
		console.log(this.name)
	}
}
Fn()();// 輸出 123
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章