1. 程式人生 > >ECMAscript 學習筆記(02)

ECMAscript 學習筆記(02)

this cast nsnull 學生 all key undefine per class

# 知識點整理(02)
## 1.小知識點
1. **使用typeof關鍵字獲取null的類型 獲取到的是 ‘object‘**
? <!--但是 其實他是一個 值類型的數據-->

**這裏的null無法確定到底是引用類型還是值類型,所以,我們根據概念性的東西,** **也就是使用typeof關鍵字獲取到null的類型為object 證明他是引用類型**
? **NULL null nil NSNull**
## 2.面向對象的三大特性
<script>

1. //封裝 var name = "張學友"; var age = 18; function sayHello(){ console.log("hello world"); } var obj = { name : "劉德華", age : 50, sayHello : function () { //..... } } var itcast = { getEle:{ }, } 2. //繼承 //javaScript當中的繼承是指 //一個對象沒有一些方法和屬性,但是另外一個對象有 //把另外一個對象的屬性和方法,拿過來使用,就是繼承 var obj = { }; var obj1 = { name : "張學友", sayHello: function () { console.log("你好,我是張學友"); } } //obj.sayHello(); //混入式繼承(mix-in) for in for(var k in obj1){ //k可以獲取到對象的每一個屬性 //obj1[k]可以獲取到對象的每一個屬性的值 //這裏使用k給對象新增屬性的時候,不可以使用點語法 obj[k] = obj1[k]; } obj.sayHello(); //java //Class //Class Person(){ // string name; // int age; // public void sayHello(){ // } // } //Class Student:extend Person{ // // } // console.log(obj); 3. //多態 //多態是在強類型語言中比較常用,JavaScript中沒有相應的體現 //Animal 父類 父類的屬性和方法供所有的子類共享 但是父類不能訪問子類的屬性和方法 //Dog 子類 //Cat 子類 //Animal an = new Animal(); //Dog dog = new Dog(); //Animal an = new Dog(); //使用父類的引用(指針)指向子類的對象 就叫做多態 //使用多態來隱藏不同 </script>
## 3.創建對象的3種方式(不適合批量創建和復用)
<script> //如何創建一個對象 //1.對象字面量 {key:value,key:value...} //只能創建一次對象,復用性較差,如果要創建多個對象,代碼冗余度太高 var obj = { name:"演員", singer:"薛段子手", type:"流行" }; var obj1 ={ name:"吻別", singer:"張學友", type:"流行" } //2.使用內置構造函數 var obj = new Object(); obj.name = "一千個傷心的母牛"; obj.singer = "張學友"; obj.sing = function () { console.log("一千個傷心的母牛"); } var obj1 =new Object(); obj.name = "一千個傷心的母牛"; obj.singer = "張學友"; obj.sing = function () { console.log("一千個傷心的母牛"); }

//3.封裝簡單的工廠函數 (不推薦使用了)
function createSong(songName,singerName){ var o =new Object(); o.name = songName; o.singer = singerName; o.sing = function () { console.log("讓我來唱首歌"); } return o;//{name:"",singer:"",sing:function...} } var obj = createSong("演員","薛之謙"); var obj1 = createSong("一言難盡","張宇");

? ## 4.自定義構造函數的方式創建對象1
<script> //創建對象的方式 //4.自定義構造函數 Object Array //什麽是構造函數? //構造函數其實也是函數,但是通常用來初始化對象 //並且和new關鍵字同時出現 //new 是用來創建對象的 //構造函數時用來初始化對象的(給對象新增成員) //構造函數名,首字母要大寫!!!以示區分 function Person() { //默認隱含的操作,把剛才用new新創建出來的對象賦值給this this.name = "尼古拉斯凱奇"; this.age = 50; this.sayHello = function () { console.log("Hey man"); } //如果這裏寫其他的代碼,會執行嗎? 肯定會 return null; } var p = new Person();//new Object(); console.log(p); p.sayHello(); //構造函數的執行過程 //1.使用new關鍵字創建對象 //2.調用構造函數,把新創建出來的對象賦值給構造函數內的this //3.在構造函數內使用this為新創建出來的對象新增成員 //4.默認返回新創建的這個對象 (普通的函數,如果不寫返回語句,會返回undefined) //構造函數的返回值 //1.如果不寫返回值,默認返回的是新創建出來的對象 (一般都不會去寫這個return語句) //2.如果我們自己寫return語句 return的是空值(return;),或者是基本類型的值或者null,都會默認返回新 創建出來的對象 //3.如果返回的是object類型的值,將不會返回剛才新創建的對象,取而代之的是return後面的值 </script>
### 4.1自定義構造函數創建對象2

<script> function test() { console.log(this); } test(); //對象是無序的鍵值對兒的集合 function Animal(name, type, barkWay) { this.name = name; this.type = type; this.bark = barkWay; } //註意:如果像使用正常的函數一樣使用構造函數 //構造函數中的this將不再指向新創建出來的對象(因為根本就沒有創建對象) //構造函數中的this這個時候指向的就是window全局對象 //當使用this給對象添加成員的時候,全部都添加到了window上 Animal("","",function () { console.log("我是函數"); }); //這是一個錯誤的演示 window.bark(); var dog = new Animal("大黃","BYD",function () { console.log("汪汪汪"); }); console.log(dog); var cat = new Animal("小花","BSM",function () { console.log("喵喵喵"); }); console.log(typeof cat); // console.log(cat); //js中提供了兩個方法來調用其他對象的方法 //call //apply //獲取具體類型的方式 //var typeStr = Object.prototype.toString.call(想獲取類型的對象) //typeStr = typeStr.slice(8, -1) var o = {}; //構造函數是Object var b = []; //構造函數Array var c = /sdfa/; </script>
## 5.傳統的構造函數創建對象存在的弊端



<script> //寫一個構造函數,用來創建學生對象 //屬性:姓名 年齡 身高 體重 //行為:學習 吃飯 看片 把妹 function studyMethod(){ console.log("我叫"+ this.name +"Good Good Study Day Day Up"); } function Student(stuName) { this.name = stuName; this.study = studyMethod; //方法* 8*10^20 } //如果構造函數沒有參數,那麽在調用的時候 小括號 可以省略 var stu = new Student("高金彪"); stu.study(); var stu1 = new Student("李嘉欣"); stu1.study(); 結論: //如果在構造函數中定義函數,那麽每次創建對象,都會重新創建該函數 //但是函數內部代碼完全相同,就造成了資源浪費 //為了處理這個問題,我們要讓所有的對象共用一個方法 //在構造函數外部定義好該函數,將該函數賦值給構造函數內的方法 //使用這種方式寫好的方法中的this指向的就是調用該方法的對象 //this 誰調用就是誰 //使用這種方式存在的問題 //1.全局變量增多,造成汙染 //2.代碼結構混亂,不易維護 </script>
## 6原型
**因為傳統的自定義構造函數創建的對象有弊端 所以可以使用 原型對象 來進行問題的化簡**

<script> function Person(name, status) { this.name = name; this.status = status; this.act = function () { console.log("演戲"); }; this.exercise = function () { console.log("就不強身健體,就要保衛祖國"); } } var p = new Person("xyz","single"); // p.exercise();

//原型是個什麽玩意兒? //在構造函數創建出來的時候,系統會默認的幫構造函數創建並關聯一個神秘的對象,這個對象就是原型 //原型默認的是一個空的對象 //原型的作用 //原型中的屬性和方法 可以被使用該構造函數創建出來的對象 使用 //如何訪問構造函數的原型 // 構造函數.prototype console.log(Person.prototype); console.log(p.prototype); //註意 prototype是構造函數的屬性,跟對象沒有關系 //如何給原型對象添加屬性和方法? //使用對象的動態特性 Person.prototype.exercise = function () { console.log("強身健體,保衛祖國"); } p.exercise(); //當使用對象去訪問屬性和方法的時候 //會首先在對象自己內部進行查找,如果找到了,就直接使用 //如果沒有找到,就去原型中查找,查找到之後,使用 //如果原型中還沒有, 如果是屬性,就是Undefined //如果是方法,就報錯 //p.sing(); //本身和原型中都沒有 就報錯 </script>
## 7.原型對象的作用

<script> function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; this.sayHello = function () { console.log("你好我是" + this.name); } } var p =new Person("張學友",18,"male"); var p1 = new Person("劉德華",19,"male"); Person.prototype.sayHello = function () { console.log("你好我是" + this.name); } Person.prototype["sing"] = function () { console.log("一千個傷心的母牛"); } p.sayHello(); p1.sayHello(); p.sing(); p1.sing(); //如何使用原型來解決構造函數存在的問題? //構造函數的原型對象中的成員,可以被該構造函數創建出來的所有對象訪問 //而且,所有的對象共享該對象 //所以,我們可以將構造函數中需要創建的函數,放到原型對象中存儲 //這樣就解決 全局變量汙染的問題 以及 代碼結構混亂的問題 </script>
## 8.原型的相關概念和註意點
### 8.1 構造函數(系統默認創建的該構造函數的**原型對象**) —— 實例化出來的對象
<script> //實例化 //通過構造函數創建對象的過程 就叫做實例化 function Person() { } var p = new Person(); //實例化 //實例 //通過構造函數實例化出來的對象就是該構造函數的一個實例 //說實例的時候,一定要指定好構造函數 某某某 是 某某某構造函數的實例 </script>



## 9.原型的使用方法
<script>
function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } //原型的使用方法 //1.利用對象的動態特性給原型對象添加成員 //2.直接替換原型對象 //如果使用第二種方式使用原型,那麽會出現如下問題: //在替換原型之前創建的對象的原型 和 在替換原型對象之後的創建的對象 //的原型 不是同一個! Person.prototype.sayHello = function () { console.log("Nice to meet you all"); } var p = new Person("劉能", 18, "male"); p.sayHello(); //替換了原型對象 Person.prototype = { msg : "你猜我在不在" }; var p1 = new Person("xzy",18,"male"); console.log(p1.msg); // p1.sayHello(); //不能 p.sayHello(); //不能 // var o = { // name : "" }; o.name = "趙四兒"; </script> ### 9.1使用原型的註意點

<script> 使用原型的註意事項 1.使用對象訪問屬性的時候,如果在本身內找不到就會去原型中查找 但是使用點語法進行屬性賦值的時候,並不會去原型中進行查找 使用點語法賦值的時候如果,對象中不存在該屬性,就會給該對象新增該屬性,而不會去修改原型中的屬性 2.如果在原型中的屬性是引用類型的屬性, 那麽所有的對象共享該屬性,並且一個對象修改了該引用類型屬性中的成員,其他對象也都會受影響 3.一般情況下不會將屬性放到原型對象中 一般情況下原型中只會放需要共享的方法 function Person(){ } Person.prototype.name = "張三"; Person.prototype.age = 18; var p = new Person(); console.log(p.name); p.name = "李四"; console.log(p.name); var p1 = new Person(); console.log(p1.name); var x = { brand:"laosilaisi", type:"huanying" }; Person.prototype.car = x; var p = new Person(); console.log(p.car.brand); Person.prototype.car = { brand:"BYD" }; var p1 =new Person(); console.log(p1.car.brand); p.car = { }; var p1 = new Person(); console.log(p1.car.brand);、 </script> ### 9.2 __proto__屬性

<script> function Person() { } 1.通過構造函數訪問原型 Person.prototype Person.prototype.msg = "在不在!"; var p = new Person(); 2.通過對象訪問原型 __proto__屬性 (是由原型對象提供的) __proto__是一個非標準的屬性 為了保證通用性 這個屬性不推薦使用 __proto__屬性的用途 主要用來做調試 console.log(p.__proto__); p.__proto__.sayHello = function () { console.log("你好") } p.sayHello(); </script>
### 9.3 constructor 原型對象中 的 構造屬性
<script> //原型對象在創建出來的時候,會默認的有一個constructor屬性 //指向對應的構造函數 function Person(){ } console.log(Person.prototype.constructor); Person.prototype = { constructor : Person }; console.log(Person.prototype.constructor); 1. 在使用新的對象替換掉默認的原型對象之後 2. 原型對象中的constructor屬性會變成 Object 3. 為了保證整個 構造函數---原型----對象 之間的關系的合理性 4. 應做如下操作: 5在替換原型對象的時候,在新的原型對象中手動添加 constructor 屬性 </script>


後續上傳最近學習的ES6的學習筆記.. 荊軻刺秦王...
?

ECMAscript 學習筆記(02)