js基礎學習

來源:互聯網
上載者:User

標籤:直接   --   訪問   return語句   返回   取出   設定   一次函數   全域   

js視頻:
53:如果函數中return語句後邊不跟任何值就相當於返回一個undefined,
如果函數中不寫return,則也會返回undefined.
56:立即執行函數:函數定義完立即被執行。
function(){
alert("我是匿名函數");
}//這是一個函數對象,只不過沒有名字,要想讓她立即執行,則只需()括起來這個匿名函數,使其成為一個整體,然後在()就相當於調用

(function(){
alert("我是匿名函數");
})()//這就相當於函數對象()的形式來調用,

為什麼匿名函數要加括弧?
是因為如果不加括弧,就會把{alert("我是匿名函數");}當作一個代碼塊處理,而前邊的function()就多餘出來,會報錯。加上括弧就是作為一個整體,成為函數對象,跟下邊的a一樣
var a=function(){
alert("我是匿名函數");
}//a就是函數對象,要想執行,則只需a()
還可以給其傳參數:
(function(a,b){
console.log(a);
console.log(b);
})(123,456)//給a傳123,給b傳456

58:變數的聲明提前:
使用var關鍵字聲明的變數,會在所有代碼執行之前被聲明(但並未被賦值),下面兩種等效:
console.log("a="+a);//結果:a=undefined
var a=123
即:
var a;
console.log("a="+a);//結果:a=undefined
a=123;
以上等效,如果變成:
console.log("a="+a);//結果:會報錯。因為a還沒有聲明。
a=123;
58:函數的聲明提前:
a.使用函式宣告形式建立的函數function 函數名(){}
它會在所有的代碼執行之前就被建立,所以可以在此函數定義出現之前就調用函數。
fun();//調用在前,定義在後,不出錯,會列印出haha
function fun(){
console.log("haha");
}
b.使用函數運算式建立的函數,不會被提前,所以不能在函數定義前調用。
fun2();//報錯
var fun2=function(){
console.log(‘haha‘);
}
58:js中一共有兩種範圍:
a.全域範圍:
-直接編寫在script標籤中的js代碼,都在全域範圍
-全域範圍在瀏覽器頁面開啟時建立,在頁面關閉時銷毀
-在全域範圍中有一個全域對象window,它代表的是一個瀏覽器視窗,由瀏覽器建立,可以直接使用
-在全域範圍中,
建立的變數都會作為window對象的屬性儲存
建立的函數都會作為window對象的方法儲存
-全域範圍中的變數都是全域變數,在頁面的任意部分都可以訪問的到。
b.函數範圍:
-調用函數時建立函數範圍,函數執行完後,函數範圍銷毀。
-每調用一次函數就建立一個新的函數範圍,他們之間是獨立的
-函數範圍可以訪問全域的,反之則不行。
var c=33;
function fun(){
console.log("c = "+c);
var c=10;
}
fun();//會輸出c = undefined,因為函數範圍中有,故變數聲明提前。不會採用全域的。
59:a.在函數中不使用var聲明的變數都是全域變數。
var c=33;
function fun(){
c=10;
d=100;
}
fun();
console.log("c = "+c);//c也成為全域,c = 10
console.log("d = "+d);//d是全域,d =100
b.定義形參就相當於在函數範圍中聲明了變數。
var e=23;
function fun(e){
console.log(e);
}
fun();//會顯示undefined,因為這時候相當於在函數中有var e;
60:舉兩個例子:
1) var a=123;
function fun(){
alert(a);
a=456;
}
fun();//調用函數,得到123
alert(a)//456
2) var a=123;
function fun(a){//與1相比,多了一個形參,則相當於在函數中聲明了變數var a
alert(a);
a=456;
}
fun();//調用函數,得到undefined,因為a已經聲明了
alert(a)//123.因為456改變的是函數範圍聲明的a
3)alert(c);//會報錯,因為c沒有聲明,
c=true;
61:解析器即瀏覽器在調用函數時,每次都會向函數內部傳遞進一個隱含的參數,這個參數就是this
根據函數調用方式的不同,this指向不同的對象
a.以函數形式調用時,this永遠都是window
var name="全域";
function fun(){
console.log(this.name);
}
fun();//以函數形式調用,所以this是window,而window.name是全域,所以:全域

b.以方法形式調用時,this是調用方法的那個對象
function fun(){
console.log(this.name);
}
var obj={
name:"haha",
sayHello:fun
}
console.log(obj.sayHello==fun)//true
obj.sayHello();//haha,
c.當以建構函式形式調用時,this就是新建立的那個對象
62:d.要注意以下:
var name="全域";
function fun(){
console.log(name);//要注意這裡不再是this.name
}
fun();//全域
var obj={
name:"haha",
sayHello:fun
}
obj.sayHello();//這裡是重點。結果:全域,因為name在函數中未找到,會去全域中找,所以是全域。這時候不是this.name
63:使用工廠方式建立大量對象核心思想:
即將要建立對象的共性部分提取出來,然後通過傳入不同參數來構建他們的不同部分。
function createPeople(name ,age){
var obj=new Object();
obj.name=name;
obj.age=age;
obj.sayName=function(){
alert(this.name);
}
return obj;
}
var obj1=createPeople("孫悟空",14);
var obj2=createPeople("豬八戒",18);
但是使用Factory 方法建立的對象,使用的建構函式都是Object,即new Object(),導致無法區分多種不同類型的對象
64:為瞭解決上述問題,可以建立一個建構函式,專門用來建立一種類型的對象,比如Person類型,Dog類型
--建構函式就是一個普通的函數,建立方式和普通函數沒有區別
不同的是建構函式習慣首字母大寫,類似java中的類名
--建構函式和普通函數的區別就是調用方式
普通函數是直接調用fun();
建構函式需要使用new關鍵字來調用: new Fun();就相當於java一樣構造對象,使用類名
a.建構函式
function Person(){}
var per=new Person();
console.log(per);//object Object
b.普通函數
function Person(){}
var per=Person();
console.log(per);//undefined,因為沒有傳回值
建構函式的執行流程:
1)立刻建立一個新的對象,//類似var obj=new Object();這樣
2)將建立的對象設定為函數中的this,在建構函式中可以使用this來引用建立對象//var per=new Person(),per就是建立對象
3)執行函數中的代碼
4)將建立的對象作為傳回值返回
function Person(){
this.name="孫悟空" //這裡的this就是per
this.sayName=function(){
alert("hello myName is:"+this.name);
}
}
var per=new Person();
console.log(per.name);//孫悟空
65:目前我們的方法是在建構函式內部建立的,也就是建構函式每執行一次就會建立一個新的sayName方法
執行10000次就會建立10000個新的方法,而10000個方法都是一樣的。可以使所有對象共用一個。
解決辦法1:將方法定義在全域範圍
function Person(){
this.name="孫悟空" //這裡的this就是per
this.sayName=fun;
}
//將函數提取到全域,但是會汙染全域命名空間,即大家名字衝突造成覆蓋,見後續的原型。
function fun(){
alert("hello myName is:"+this.name);
}
66:原型prototype
a.我們所建立的每一個函數(不管是普通還是構造),解析器都會向函數中添加一個屬性prototype
這個屬性對應著一個對象,即原型對象
b.如果函數作為普通函數調用prototype沒有任何作用
c.當以建構函式的形式調用時,它所建立的對象中都會有一個隱含的屬性指向該建構函式的原型對象
可以通過__proto__來訪問該屬性//var per =new Person(),即per中有該隱含對象
即:console.log(per.__proto__==Person.prototype)//true
d.原型就相當於一個公用地區,所有同一個類的執行個體都可以訪問到這個原型對象//per ,per1,per2都可以
e.可以將對象中共有的內容,統一設定到原型對象中,這樣就避免了全域汙染
f.當我們訪問對象的一個屬性或方法時,會先在對象自身中尋找,如有則直接使用,沒有就去原型對象中尋找。
舉例:
function Person(){
this.name="孫悟空"
}
Person.prototype.sayName=function(){
alert(this.name);
}
var per=new Person();
per.sayName();//孫悟空
g.當不想用原型中的變數或方法時,直接全域覆蓋即可,因為他首先會在自身尋找。
h.以後建立建構函式時,可以將這些對象共有的屬性和方法統一添加到建構函式的原型對象中,這樣不用分別為每一個對象添加,
也不會影響到全域範圍,這樣每個對象都有了。

可以詳細再看看本集視頻。
67: 1) 使用in檢查對象中是否含有某個屬性時,如果對象中沒有但是原型中有,也會返回true,//所以就顯得不夠精確
2) 可以使用對象的hasOwnProperty()來檢查對象自身中是否含有該屬性。
function MyClass(){

}
MyClass.prototype.name="孫悟空";
var mc =new MyClass();
console.log("name" in mc);//true
console.log(mc.hasOwnProperty("name"));//false
console.log(mc.hasOwnProperty("hasOwnProperty"));//false,因為本身也沒有這個方法,會往上找原型
console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));//false,發現原型裡也沒有這個方法
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//true,原型裡沒有後,會去原型的原型裡去找
console.log(mc.__proto__.__proto__);//[object Object]
console.log(mc.__proto__.__proto__.__proto__);//null,到頭了

即:當我們使用一個對象的屬性或者方法時,會在自身中尋找,自身如果有,則直接使用;
若沒有則去原型對象中找,如果原型對象中有則使用;
若仍然沒有,則會去原型的原型中去尋找,直到找到Object對象;
Object對象的原型沒有原型,如果在Object中仍沒有找到某個屬性或方法,則返回undefined
一般也就使用兩級proto,即console.log(mc.__proto__.__proto__);就到頭了
68:當我們直接在頁面中列印一個對象時,實際輸出的是對象的toString()方法的傳回值。
如果我們希望在輸出對象時不輸出[object Object],可以為對象添加一個toString()方法。
var per = new Person("孫悟空",18,"男");
console.log(per);//[object Object]
per.toString=function(){//但是這樣只是修改此對象,其他對象依然還是[object Object]
return "haha";
}
console.log(per);//haha
所以可以這樣搞,給原型對象添加
Person.prototype.toString=function(){
return "haha";
}
或者:
per.__proto__.toString=function(){
return "haha";
}
這樣建立的每個對象都可以使用了。
69:記憶體回收:var obj=new Object();
obj=null;//js會自動進行記憶體回收。只有沒有引用此對象,所以對於不使用的對象,可以將引用變為null
70:js對象三種:內件對象,宿主對象,自訂對象
w3school離線手冊有內建對象的介紹。
永遠向數組的最後一個位置添加元素,不用記索引值:arr[arr.length]=70;
arr[arr.length]=80;
arr[arr.length]=90;//不用記索引,直接在最後添加。
71:

js基礎學習

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.