2014年5月30日 星期五

[js] JavaScript的"類別"用法 ~2~

類別的建立方式收集

1. 
var Person = function(_name, _age){
  this.name = _name;
  this.age = _age;
};

2. 
var Person = function(_name, _age){
  return {
    name: _name,
    age: _age
  }
};

3. 
// 匿名類別
var p = (function(){
  return {
    name: _name,
    age: _age
  };
}());

4.
// 隔空發功建立物件
var p;
(function(){
  p = {
    name: _name,
    age: _age
  };
}());


[js] 繼承

接下來的主題是繼承

繼承的目的是為了程式的重用

而當我們使用JavaScript並且透過new關鍵字和function來建立類別時

其實物件裡面的attribute都是被獨立建立起來的 (物件裡面的method也算是attribute的一種)

ex.
  var Person = function(_name, _age){
    this.name = _name;
    this.age = _age;
    this.hi = function(){
        console.log(this.name +" say: hi!");
    };
  };

  var p1 = new Person("小明", 18);
  var p2 = new Person("花花", 15);
  p1.hi();
  p2.hi();
  console.log(p1.hi == p2.hi); //false

實際上要真正的共用同一個function會需要引入prototype的概念

ex.
  var Person = function(_name, _age){
    this.name = _name;
    this.age = _age;
  };

  Person.prototype.hi = function(){
    console.log(this.name +" say: hi!");
  };

  var p1 = new Person("小明", 18);
  var p2 = new Person("花花", 15);
  p1.hi();
  p2.hi();
  console.log(p1.hi == p2.hi); //true

談到prototype雖然從共用講起

但是特別該注意的是p1.hi 與 p2.hi其實並沒有直接bind在物件上面

而可以對應得到method是因為object在進行attribute的存取時的原則!!!













[js] this的討論

測試不使用chrome來測試了,改用node js!!

要使用瀏覽器測試直接調整global成window就可以。

var Method = function(str, obj){ console.log(str); console.log("\tthis:"+this); console.log("\tthis == global:"+(this == global)); console.log("\tthis == o:"+(this == o));
if(typeof obj != 'undefined'){
console.log("\tthis == obj:"+(this == obj));
}
if(this != global){
this.method = Method;
};
} var o = { method: Method };
// this == global Method("Method();");

// this == global
console.log("this == global:"+(this== global));

// this == o o.method("o.method();");


var inst = new Method("new Method();");
// this == obj => this == inst
inst.method("inst.method()", inst);

----

在這段程式的執行結果可以看到,直接呼叫method的時候,this是對應到全域的
global
另外全域的this也是

而o.method則是對應到物件本身

最後兩個則是確認new Method()確實會回傳一個新的物件 而且是this

[js] JavaScript的"類別"用法 ~解析~

上篇主要說明了js function模擬類別的用法

細節有幾個部分可以說說

1. 宣告了function可以直接呼叫,也可以加上new當作建構式來用
    差別是this與prototype設定 (prototype介紹繼承再介紹吧)

2. 如果裡面沒有回傳值,在當作建構式使用時,會回傳this物件
    如果裡面回傳的是Primitive Data Type時,預設也會回傳this物件
    如果裡面有回傳物件,就是直接回傳新的物件

3.  當我們宣告var fn = function(){};的時候其實也是在宣告一個attribute fn
     只是它是個function object

4. 當在function中存取一個attribute
    而且如果沒有在function裡面宣告的話
    會往"外面"尋找相同名字的attribute

5. private attribute與method是利用第3,4來完成的
建立不能直接存取到的method與attribute
(硬是要應該還是可以啦 = =)

6. 第4點說的"外面"指的是外面的scope (JavaScript是以function來區分scope)
     所以會往這個function的外面的function來尋找
     而不會找本身所在的物件所擁有的function(不會從this先找起)

ex.
// 以下範例使用getCoord()
// 預設找外面的function的getCoord而不是本身物件的getCoord
var Person = function(_name, _age){
var x = 10,  
y = 15;  
var getCoord = function(){  
return "("+x+","+y+")";
};

this.name = _name,
this.age = _age,
this.moveX = function(step){
x += step;
};
this.moveY = function(step){
y += step;
};
this.getCoord = function(){
return "["+x+","+y+"]";
};
this.hi = function(){
return this.name+"在"+getCoord()+":hi!";
};
};
var p = new Person("丹丹", 18);
p.hi(); // 丹丹在(10, 15): hi!

Q. 範例的hi() 如果把this.name 改成name會如何?

A. 因為在hi()裡面找不到name所以會到Person()裡面找
但是Person()也找不到就會找global的name
應該會出現name is not defined的錯誤訊息
       but 在chrome中測試,window裡面有個神奇的name屬性
       所以.... 其實也不會出錯啦~~

       ps. 用node js測試就出現錯誤訊息啦!!!

ReferenceError: name is not defined
    at hi (repl:20:8)
    at repl:1:3
    at REPLServer.self.eval (repl.js:110:21)
    at repl.js:249:20
    at REPLServer.self.eval (repl.js:122:7)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)

[js] JavaScript的"類別"用法

一般寫Java或者是其他物件導向的程式語言時
我們使用物件中的method或是attribute如果在本身物件中找不到
就會往自己的繼承來的method或者是attribute尋找

JavaScript裡面並沒有直接繼承這樣的語法,畢竟沒有類別咩~~

JavaScript首先透過function提供類似建構式的用法,更可以用來模擬類別

用法如下,介紹留待下篇講解~

建構式用法


var Person = function(){};
var p = new Person();

增加attribute


var Person = function(_name, _age){
  this.name = _name;
  this.age = _age;
};

var p = new Person("丹丹", 18);
console.log(p.name +"("+p.age+")");

增加method


var Person = function(_name, _age){
    this.name = _name;
    this.age = _age;
    this.hi = function(){
      console.log(this.name+":hi!");
    };
};

var p = new Person("丹丹", 18);
console.log(p.name +"("+p.age+")");
p.hi();

增加private attribute跟method


var Person = function(_name, _age){
  var x = 10,
y = 15;
  var getCoord = function(){
    return "("+x+","+y+")";
  };
  this.name = _name;
  this.age = _age;
  this.moveX = function(step){
    x += step;
  };
  this.moveY = function(step){
      y += step;
  };
  this.hi = function(){
    return this.name+"在"+getCoord()+":hi!";
  };
};

var p = new Person("丹丹", 18);
p.hi();  // 丹丹在(10, 15): hi!
p.moveX(5);
p.hi();  // 丹丹在(15, 15): hi!



2014年5月25日 星期日

[js] JavaScript裡面只有物件沒有類別。

一般來說想到寫OO,大概會先想寫個類別然後new一下

很開心的就可以來宣稱[這就是OO啦]

OOP的特性印象中是封裝、多型、繼承

老實說越看越感覺"說得很明確,感覺很模糊"

(好吧,討論OO下去這篇根本就歪掉了)

總之,OO其實只是我們一種組織邏輯的方式

依照職責分工、允許有各自不同的細節、實作可以重複利用等等

特性的部分應該只是歸納後的重點

分類管理做得好,大而不肥,粗中帶細,才是真正的OO啦!!!

---

與一般OO程式語言先寫Class(權責分類)再建立Object(程式重用)不同

JavaScript則是建立Object(先有能用的程式)... 然後"結束"...

例如:
var person = {
    name: "小明",
    age: "18",
    hi: function(){
        console.log(name+"是個"+age+"歲的年輕人");
    }
};
person.hi();

也就是JavaScript的特性允許我們馬上開始建立能用的程式!!

其實幾行甚至一兩百行的小程式這樣寫也不是什麼大問題

問題還是出在管理上,這樣子的程式越來越多,一天有個幾百行,一個月...一年...

零散沒有組織的邏輯,只會搞死後來維護的人。


根據這樣的基礎,我們應該思考衍生出來的後續問題

該怎麼合理有效的組織js物件

如何建立物件?

如何分類物件?

如何讓很多不同的物件可以活在同一個頁面上,又彼此獨立不會相互影響?

如何讓物件是一個獨立的個體,又足夠開放給外部功能做存取?

js很有意思的!!!


回過頭來,雖然js允許我們利用不OO的方式組織程式

但是透過寫物件與一些語法的性質,我們一樣可以建立有OO感的js程式 <3

也就是說... 程式寫不好大部份還是人的問題啦...

[js] JS記錄文系列 ~start~

標題的小小start,代表著這次弱弱的決心

主要是JavaScript的一些觀念,平常實在不常用,但是就還是會用到 @"@

只好來做整理!!

目標並不是要做細節的介紹,而是整理目前覺得重要的重點,跟實際的範例

範例的部分會使用jsfiddle來幫忙

基本的框架會有jQuery, bootstrap等,主要以本人閱讀容易為準。

隨時會調整的大綱如下:

  1. js裡面只有object,沒有class
  2. js的物件建立模式 - 1, 2, 3, .... (這應該需要系列文,主要從javascript pattern中整理)
  3. js程式的模組化模式
  4. function scope
  5. this
  6. prototype





2014年5月24日 星期六

[css] Selector & Combinator

順手記錄下~
原來一直弄錯以為combinator也應該叫做selector但是其實不是 XDD
這種含有關係的selector應該叫做combinator(組合器?)

selector

element
  就是html tag的選擇器
  例如:html, input, p, ...
#id
  如果我們有指定id給某個element, 就是選取有著此id的element
  例如:#datalist, #menu
.class
  如果我們有指定class給某個element, 就是選取有著此class的element

id與class差別是,id在整個頁面是要唯一的,但是class不需要
(這應該可以從名字就看得出來了,但是硬是不這樣用...誰拿你有辦法?)
在bootstrap裡面就定義了很多class給我們用.btn, .table等等
  

Combinator

看到descendant 跟child都要介紹,應該很明顯有英文單字詞彙不夠的感覺。

    descendant: 子孫
    child: 孩子, 小孩
    sibling: 兄弟

明顯是想混淆我們啊!!!!!! 這樣技術會比較值錢嗎?

descendant selector
    ex. div p:選擇div裡面所有的p

child selector
   ex. div > p:選擇剛好在div下一層的p

general sibling selector
   ex. div~p:選擇div之後所有的p

adjacent sibling selector
   ex. div+p:選擇剛剛好在div之後的一個p

這裡有飯粒:
    http://jsfiddle.net/progden/gd2Lx/
    http://jsfiddle.net/progden/Mf6zT/