// 1、字面量創建 var per1 = { name: '張三', age: '18', eat: function () { console.log('吃東西') } } // 2、Object方式創建 var per2 = new Object() per2.name = '李四'; per2.age = '18'; per2.read = function () { console.log('讀書') } // 3、通過工廠模式創建 function person(name,age) { var obj = new Object(); obj.name = name; obj.age = age; obj.play = function () { console.log('玩游戲') } return obj } var per3 = person('王五','20') // 4、通過構造函數創建 function animal(name, age) { this.name = name; this.age = age; this.food = function () { console.log('骨頭') } } var ani1 = new animal('泰迪',3) // ani1稱為實例化對象 console.log(ani1.__proto__ === animal.prototype) // true 兩者都是指向構造函數的原型 console.log(ani1.__proto__.constructor === animal.prototype.constructor) // true 兩者都指向的是構造函數 console.log(ani1 instanceof animal) // true 以此來判斷對象是不是這種數據類型
JS面向對象 構造函數的執行流程: 1、立刻創建一個新的對象 2、將新建的對象設置為函數中的this 3、逐行執行函數中的代碼 4、將新建的對象作為函數值返回 使用同一個構造函數創建的對象,我們成為一類對象,也將一個構造函數成為一個類, 我們將通過一個構造函數創建的對象,稱之為該類的實例 1、當以函數的形式調用時,this是window 2、當以方法的形式調用時,誰調用方法this就是誰 3、當以構造函數的形式調用時,this就是新創建的那個對象 提升系統性能,不管實例化多少次對象,這個函數都只會調用一次,如果是寫在構造函數內,則 每一個實例化時都會調用。 但是這樣就將函數定義在了全局作用域中,污染了全局作用域的命名 空間,而且在全局作用域中也很不安全(通過原型鏈的方式向原型中添加fun方法可以保證函數不在全局作用域中,且只會執行一次) JS原型(prototype) 我們所創建的每一個函數,解析器都會向函數中添加一個屬性prototype 這個屬性對應着一個對象,這個對象就是我們所謂的原型對象 當函數以構造函數調用時,所創建的對象中都會有一個隱藏的屬性執行該構造函數的原型對 象 原型對象就相當於一個公共的區域,所有同一個類的實例都可以訪問這個原型對象 我們可以將對象中共有的內容,統一設置到原型對象中。 當我們訪問對象的一個屬性或方法時,它會先在對象自身中尋找,如果有則直接使用 沒有則會通過__proto__向原型對象中找,如果還是沒有,則會在原型的原型上找,一直向上,一直找到object對象原型中(最終),如果有則返回,如果沒有則返回undefined 以后我們創建構造函數時,可以將這些對象共有的屬性和方法,統一添加到構造函數的原型對象中,這樣不用分別為每一個對象添加,也不會影響到全局作用域,就可以使每個對象都具有這些屬性和方法了 function Person(name,age) { this.name = 'name'; this.age = 'age'; this.say=function () { console.log(this.name) } } var obj = new Person('aa',18); Person.prototype.sex = 'man'; console.log(obj.sex)//man