解析器在調用函數每次都會向函數內部傳遞一個隱含參數,即this,this指向一個對象,此對象稱之爲函數執行的上下文對象,根據函數調用的方式不一樣,this指向不一樣的對象.安全
1.以函數的形式調用時,this永遠指向window
2.以方法的形式調用時,this就是調用方法的那個對象app
其實就是誰調用,指向誰,由於以函數的形式調用就是省略了window的調用函數
3.當以構造函數的形式調用時,this指向新建立的對象
4.使用call和apply調用時,this指向指定的那個對象this
使用工廠方法建立對象,能夠大批量建立code
function creatPerson(name, age, sex) { // 建立一個新的對象 var obj = new Object(); //向對象中添加屬性 obj.name = name; obj.age = age; obj.sex = sex; // console.log(this) 此處this obj.sayName = function() { console.log(this.name) //此處this } // 將新的對象返回 return obj } var person = creatPerson('zhangsan', 18, 'man')
構造函數就是一個普通函數,建立方式沒有區別,習慣上首字母大寫
構造函數和普通函數的區別就是調用方法不一樣:
普通函數直接調用,構造函數使用new關鍵字調用對象
構造函數的執行過程:內存
function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; // console.log(this.name) this.sayName = function() { console.log(this.name) } } var per = new Person('zhangsan', 18, 'man')
使用同一個構造函數建立的對象,稱之爲一類對象,也將一個構造函數稱爲一個類。
咱們將經過一個構造函數建立的對象,稱之爲這個類的實例
使用instanceof 能夠檢查一個對象是不是一個類的實例
語法:
對象 instanceof 構造函數
是,返回true;不然,返回false
console.log(per instanceof Person)作用域
console.log(per.sayName === per1.sayName)
在Person構造函數中,爲每個對象都添加了一個sayName方法,目前咱們的方法是在構造函數內部建立的,也就是構造函數每執行一次就會建立一個新的sayName方法,也就是全部的sayName都是不一樣的,若構造函數執行10000次就建立了10000個方法,消耗內存get
function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.sayName = fun; } //將sayName方法放在全局做用域下定義 function fun() { console.log(this.name) }
將函數定義在全局做用域中,污染了全局做用域的命名空間,也不安全io
1.this是什麼?
任何函數本質上都是經過某個對象來調用的,若沒有直接指定調用者,默認是window
全部函數內部都有一個變量this
它的值是調用函數的當前對象
function Person(color) { console.log('Person:', this) this.color = color; this.getColor = function() { console.log('getColor', this) return this.color } this.setColor = function(color) { console.log('setColor', this) this.color = color } } Person('red') // this指向window var p = new Person('blue') // this指向p var obj = {} p.setColor.call(obj, 'pink')// this指向obj var test = p.setColor test() // this指向window