JavaScript 作用域
一般語言的作用域分兩大種
1. 以代碼塊為作用域
2. 以函數作為作用域
相對於其他的語言的作用域以代碼塊為作用域
例如 JAVA
public void Func(string v){ if (1==1){ string name='Java'; } console.writeline(name); }
如上就會報錯:因為是以一個代碼塊為作用域
Python : 以函數作為作用域
def func(): if 1==: name='alex' print(name) func()
一:以函數作為作用域(除去let)
那麽JavaScript 是以什麽為作用域呢?
答案是以函數作為作用域
例如:
xo="liang"; function func(){ var xo='eric'; function inner(){ console.log(xo); } return inner; } var ret=func() ret()
執行的結果為eric
那麽為什麽會執行的為eric 首先是解析func 函數中的代碼。執行到function inner 就不會執行了
就會跳到下return inner 其實ret 就是inner 的內存對象而已了。加了一個()之後就會執行inner 這個函數體
再來一個例子:
xo="liang"; function func(){ var xo='eric'; function inner(){ console.log(xo); } xo='tony'; return inner; } var ret=func() ret()
執行的結果是tony 這個是為什麽呢?
首先我們看看代碼 xo 的是賦值了兩次。代碼是遵循這一條條解析的。到了第二次賦值的時候,xo已經變為 tony
那麽後面再去執行inner 這個函數的時候執行的結果就是tony 其實可以改一下代碼,就看的更清晰了如下:
xo="liang"; function func(){ var xo='eric'; var xo='tony'; function inner(){ console.log(xo); } return inner; } var ret=func() ret()
改成這個樣子之後就更清晰了,
總結一下 就是函數的作用域 未被調用之前 已經創建了
還有一個是函數的做用鏈 比如:
function func(){ function inner(){ }}
其實在調用之前是已經創建好了的作用鏈 也就是多層函數嵌套
4.函數內局部變量提前聲明
function func(){ console.log(xxoo); }
執行這個時候就會報錯
function func(){ console.log(xxoo); var xxoo='print'; }
但是執行這個時候就不會。因為默認函數內的局部變量就會聲明一個undefined
就是說,在調用之前,xxxx=undefined 執行 console.log(xxoo); 的時候就會輸出一個undefined
JavaScript 面向對象
這個其實是很有意思的
function foo(){ var x='liang'; } fucntion Foo(n){ this.name=n; } var obj = new Foo('we'); obj.name
比如上面的一個代碼。this就相當於python中的self
一、this 代指對象(python self) 二、創建對象時、new 函數()
如果面向對象中 foo 函數中還需要嵌套一個函數呢? 那麽嘗試一下吧
function Foo(n){ this.name=n; this.sayName=function(){ console.log(this.name); } } var obj1=new Foo('we'); obj.name obj.sayName()
上面寫一個一個sayName 但是我對比了一下python 的一個面向對象的時候才發現這種是不合理的
如果我有50個對象。那麽這個
function(){ console.log(this.name);
這個代碼就會在每一個對象裏面進行創建。而python 是這個函數就放在類裏面的。
例如這樣的
class School(object): def __init__(self,name,addr): self.name=name self.addr=addr self.students=[] self.teachers=[] def ronle(self,stu_ojb): print("為學生註冊 %s"%stu_ojb.name) self.students.append(stu_ojb) def hire(self,teac_obj): print("添加新員工%s"%teac_obj.name) self.teachers.append(teac_obj) t1=Teache("liang",22,'F',12000,"Linux") t2=Teache("liang2",22,'F',12000,"Python"
我的t1 和t2 只需要去類裏面去找 hire 這個方法。而不是去自己裏面去定義這個方法
那麽這個就引出了面向對象裏面的原型:
那麽解決的方法如下:
原型: function Foo(n){ this.name=n; } // Foo 的原型 Foo,prototype={ 'sayName':function(){ console.log(this.name) } } obj1=new Foo('we'); obj.sayName() obj2=new Foo('wee');
這樣就可以直接去類裏面去找方法了,不需要在自己定義了。
JavaScript 作用域