做動畫學物理‧課堂活動04

認識JavaScript(3/3)


JavaScript 是物件導向的程式語言

前面說過

javascript 有五種基礎型別(Primitive Type)

  • number
  • string
  • boolean
  • undefined
  • null

其他都是物件型別(Object Type)

物件要怎麼寫呢?

物件,這樣寫

JavaScript Object Notation (JSON)


//phoneA 是一個空物件
var phoneA = {};
//phoneB 是一個物件,有一些屬性與方法
var phoneB = {
    //一些屬性
    name : 'HTC10',
    price: 24000,
    isTurnedOn : true;
    //一些方法
    callOut : function(){
      console.log('撥打電話');
    },
    turnOff : function(){
      this.isTurnedOn = false;
    }
};
        

{ 成員名 : 成員值 , 成員名 : 成員值 , 成員名 : 成員值 , ........ }

注意裡面有個 this,指向 phoneB

先建藍圖,再創物件

藍圖,就是 function


var Phone = function(_name){
    //一些屬性
    this.name = _name;
    this.price;//宣告變數,但未設值
    this.isTurnedOn = true;
    //一些方法
    this.callOut = function(){
        console.log(this.name+'撥打電話');
    };
    this.setPrice = function(_num){
        this.price = _num;
    };
    this.whoIsThis = function(){
        console.log(this.name+', this is '+this);
    };
}
        

注意裡面有很多個 this,
指向〝呼叫這段程式的那個物件〞

先建藍圖,再創物件

剛剛只是(抽象)藍圖,現在要創建(實體)物件


//根據藍圖,創建物件
var phoneA = new Phone('nameA');
var phoneB = new Phone('nameB');
var phoneC = Phone('nameC');//注意,phoneC 故意忘了 "new"
//看看剛才做了什麼
console.log('phoneA='+phoneA);
console.log('phoneB='+phoneB);
console.log('phoneC='+phoneC);//想一想:phoneC 是什麼?
//執行方法
phoneA.callOut();
phoneB.callOut();
phoneC.callOut();
//this
phoneA.whoIsThis();
phoneB.whoIsThis();
phoneC.whoIsThis();
        

一個藍圖,可以 new 成多個物件

傳值與傳址

先看看傳的例子


var aa = 15;
var bb = aa;
bb++;
console.log('bb='+bb);//bb=16,可理解,因為 bb++
console.log('aa='+aa);//aa=15,可理解,因為 aa 沒動作
        

基礎型別都是傳值

傳值與傳址

再看看傳的例子


var Person = function(_age) {
    this.age = _age;
}
var aa = new Person(15);
var bb = aa;//把 aa 傳給 bb時,傳值?/傳址?
bb.age++;
console.log('bb.age='+bb.age);//bb.age = 16,正常
console.log('aa.age='+aa.age);//aa.age = 16,aa的居然也被改了!!!
          

物件型別都是傳址

更難↓

傳值與傳址

再難一點,看看這個例子


var aa = {age:15};//aa 是一個物件
//定義一個函數
function addAge(_obj){
    _obj.age++;
}
addAge(aa);//把 aa 傳進去
console.log('aa.age='+aa.age);//aa = ???,為什麼???
          

16,物件型別都是傳址

繼續↓

傳值與傳址

加一小句


var aa = {age:15};//aa 是一個物件
//定義一個函數
function addAge(_obj){
    _obj = {age:15};
    _obj.age++;
}
addAge(aa);//把 aa 傳進去
console.log('aa.age='+aa.age);//aa = ???,為什麼???
          

15,物件型別都是傳址

說明↓

討論

第一次


var aa = {age:15};     //1.aa 是新創個物件,目前共一個物件
function addAge(_obj){
    _obj.age++;        //3.目前共只有一個物件,且物件被修改
}
addAge(aa);//2.把 aa 傳進去
console.log('aa.age='+aa.age);//所以 aa 被改變了
          

第二次


var aa = {age:15};     //1.aa 是新創個物件,目前共一個物件
function addAge(_obj){
    _obj = {age:15};/*3.新創個物件,_obj是這個新物件,不再是原來的aa了,
                        目前共兩個物件*/
    _obj.age++;     //4.目前共只有兩個物件,且較新的 _obj 物件被修改
}
addAge(aa);//2.把 aa 傳進去
console.log('aa.age='+aa.age);//所以 aa 沒被改變
          

全域變數 / 區域變數

global variable / local variable



var aa = 15;
function myFunc(){
    var bb = aa + 3;
    console.log('bb=' + bb);//區域變數,在 function 裡可讀
}
myFunc();
console.log('aa=' + aa);//全域變數,在哪裡都可讀
console.log('bb=' + bb);//區域變數,在 function 外不可讀
        

全域變數 / 區域變數

global variable / local variable



function Person(_age , _weight , _bodyLength) {
    var weight = _weight;//區域變數,外面看不到
    var bodyLength = _bodyLength;//區域變數,外面看不到
    this.age = _age;//物件屬性,外面可看到
    this.BMI = weight/bodyLength/bodyLength;//物件屬性,外面可看到
}
var peter = new Person(15 , 70 , 1.7);

console.log(peter.age);//15
console.log(peter.BMI);//24.22
console.log(peter.weight);//undefined
console.log(peter.bodyLength);//undefined
        

任務來了


  • 建立一個藍圖 Person,可以做到下列功能
  • 
    var john = new Person('John' , 15);
    var mary = new Person('Mary' , 18);
    
    console.log(john.compareAge(mary));//1.
    console.log(mary.compareAge(john));//2.
            
  • 1.我是John,他是Mary,他比我多3歲。
  • 2.我是Mary,他是John,我比他多3歲。


[半成品]