js兩種定義函數、繼承方式及區別

來源:互聯網
上載者:User

標籤:des   http   java   io   ar   問題   cti   代碼   

一:js兩種定義函數的方式及區別
  • 1:函式宣告:
function  sayA() {   alert("i am A");  }
  • 2:函數運算式:
var sayB = function() {   alert("i am B");  }
  • 區別:code
前者會在代碼執行之前提前載入到範圍中,後者則是在代碼執行到那一行的時候才會有定義
二:js兩種繼承方式及區別
  • 對象冒充
    • 臨時屬性
    • call()
    • apply()
  • 原型鏈 code
  • 繼承應選哪種 code
三:執行個體

js兩種定義函數的方式:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>js兩種定義函數的方式</title><script language="javascript">    say();     var say =function(){        alert("567");    }    function say(){        alert("123");    }  </script></head><body></body></html>//在javascript函數體內(執行範圍)聲明的變數,無論在函數體何處聲明,它將都會被提升到函數的頂部,我們稱這種現象為變數提升。 函數呢,它也有這種特性,即無論在函數體何處聲明另一個函數,它將都會被提升到函數的頂部。只是採用函數運算式和函式宣告所體現的函數提升的內容是有差別的:函數運算式和變數提升類似,只會提升函數的變數,不提升函數的定義;而函式宣告提升時,不僅僅會提升函數的聲明,函數的定義也會被提升

對象冒充:臨時屬性

function Person(name){     this.name = name;     this.say = function(){        alert(‘My name is ‘+this.name);     }}function Student(name,id){    this.temp = Person;    this.temp(name);     delete this.temp;    this.id = id;     this.showId = function(){       alert(‘Good morning,Sir,My student number is ‘+this.id);    }}var simon = new Student(‘Simon‘,9527);simon.say(); //my name id simonsimon.showId(); //Good morning,Sir,My work number is 9527

對象冒充:apply()/call():

function Person(name){    this.name = name;    this.say = function(){      alert(‘My name is ‘+this.name);    }}function Student(name,id){     Person.call(this,name); //apply():Person.apply(this,new Array(name));     this.id = id;     this.showId = function(){        alert(‘Good morning,Sir,My student number is ‘+this.id);     }}var simon = new Student(‘Simon‘,9527);simon.say();simon.showId();//apply(this,arguments):方法能劫持另外一個對象的方法,繼承另外一個對象的屬性.                         arguments:是一個數組,new Array(name,age)等//call(id,name,age)//什麼情況下用apply,什麼情況下用call  在給對象參數的情況下,如果參數的形式是數組的時候,比如apply樣本裡面傳遞了參數arguments,這個參數是數群組類型,並且在調用Person的時候參數的列表是對應一致的(也就是Person和Student的參數列表前兩位是一致的) 就可以採用 apply , 如果我的Person的參數列表是這樣的(age,name),而Student的參數列表是(name,age,grade),這樣就可以用call來實現了,也就是直接指定參數列表對應值的位置(Person.call(this,age,name,grade));  //apply和call中的參數順序以父類為準。

原型鏈繼承:new

var Shape = function(width, height) {    this.width = width;    this.height = height;};Shape.prototype.area = function() {    return this.width * this.height};var shape = new Shape(20, 30);shape.area();> 600

原型鏈繼承:無new

function Shape(width, height) {    if (!(this instanceof Shape)) {        return new Shape(width, height);    }    this.width = width;    this.height = height;    return this;}   Shape.prototype.area = function() {    return this.width * this.height};var shape = Shape(20, 30);console.log(shape.area());

 

選擇最優繼承方式:

1:在OO概念中,new執行個體化後,對象就在堆記憶體中形成了自己的空間, 值得注意的是,這個程式碼片段。而成員方法就是存在這個程式碼片段的, 並且方法是共用的。問題就在這裡,通過對象冒充方式繼承時, 所有的成員方法都是指向this的,也就是說new之後,每個執行個體將 都會擁有這個成員方法,並不是共用的,這就造成了大量的記憶體浪費。 並且通過對象冒充的方式,無法繼承通過prototype方式定義的變數和方法,如以下代碼將會出錯:

function Person(name){    this.name = name;    this.say = function(){       alert(‘My name is ‘+this.name);    }}Person.prototype.age = 20;Person.prototype.sayAge = function(){alert(‘My age is ‘+this.age)};function Student(name,id){     Person.apply(this,new Array(name));         this.id = id;         this.showId = function(){         alert(‘Good morning,Sir,My student number is ‘+this.id);     }}var simon = new Student(‘Simon‘,9527);simon.sayAge(); //提示TypeError: simon.sayAge is not a function   

2:原型鏈方式繼承,就是執行個體化子類時不能將參數傳給父類,這個例子中function Person()沒有參數。

function Person(name){    this.name = name;}Person.prototype.say = function(){    alert(‘My name is ‘+this.name);}function Student(name,id){    this.id = id;    this.showId = function(){       alert(‘Good morning,Sir,My student number is ‘+this.id); }}Student.prototype = new Person();//此處無法進行傳值,this.name或者name都不行,//直接寫Student.prototype = new Person(‘wood‘)是可以的,//但是這樣的話simon.say()就變成了My name is woodvar simon = new Student("Simon",9527);simon.say();  //彈出 My name is undefinedsimon.showId(); 

結論:

成員變數採用對象冒充方式,成員方法採用原型鏈方式function Person(name){    this.name = name;}Person.prototype.say = function(){    alert(‘My name is ‘+this.name);}function Student(name,id){    Person.call(this,name);    this.id = id;}Student.prototype = new Person(); //此處注意一個細節,showId不能寫在Student.prototype = new Person();前面Student.prototype.showId = function(){    alert(‘Good morning,Sir,My student number is ‘+this.id);}var simon = new Student("Simon",9527);simon.say();simon.showId();

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.