iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 8
0
自我挑戰組

網頁服務開發之路系列 第 8

更合理的方式寫 Javascript

複習

JavaScript For Cats

  • sentence.replace("1", "2"): 將句子中的'1' 取代成 '2'
  • console.log(): 在console 印出結果
    • console.trace(): 可以追蹤function 裡面用到的 function
  • object: var thirdCat = { name: "ceiling", lastName: "cat", address: "Attic" }
    • vs code extension: pretty json
  • callbacks: asynchronous (often shortened to async) programming

undefined

用更合理的方式寫 JavaScript (coding style)

Array

  • 直接建變數
    // bad
    var item = new Object();
    
    // good
    var item = {};
    
  • Array 增加元素時,使用 push
    var someStack = [];
    // bad
    someStack[someStack.length] = 'abracadabra';
    // good
    someStack.push('abracadabra');
    
  • 複製 Array 時,使用 silce
    var len = items.length;
    var itemsCopy = [];
    var i;
    
    // bad
    for (i = 0; i < len; i++) {
      itemsCopy[i] = items[i];
    }
    
    // good
    itemsCopy = items.slice();
    

String

  • 串連字串用 join (,)
    // bad
    function inbox(messages) {
      items = '<ul>';
    
      for (i = 0; i < length; i++) {
        items += '<li>' + messages[i].message + '</li>';
      }
    
      return items + '</ul>';
    }
    
    // good
    function inbox(messages) {
      items = [];
    
      for (i = 0; i < length; i++) {
        // use direct assignment in this case because we're micro-optimizing.
        items[i] = '<li>' + messages[i].message + '</li>';
      }
    
      return '<ul>' + items.join('') + '</ul>';
    }
    

類型轉換

  • 使用 parseInt 轉換數字時,放上基數
    // good
    var val = Number(inputValue);
    
    // good
    var val = parseInt(inputValue, 10);
    

Coding Style

  • 駝峰式命名:第一個字小寫

    // bad
    var OBJEcttsssss = {};
    var this_is_my_object = {};
    var o = {};
    function c() {}
    
    // good
    var thisIsMyObject = {};
    function thisIsMyFunction() {}
    
  • javascript 設變數的名稱,跟 document裡面的id, class, name 要相同

  • 函數命名盡量使用動詞開頭,ex. setSomeing, geSomeing, parseSomeing, toSomeing, doSomeing...

  • 算數,邏輯符號兩邊加空格,函數開頭 { 前加空格

  • 團隊討論統一

    • 使用 // FIXME 標示問題
    • 使用 // TODO 標示問題的解決方式
    • if, else 後面加空格,else 接在 } 後面
    • 縮排 2 或 4 空格,tab (?

Object Oriented for Beginners

First Step

  • Create a object: 物件有屬性與方法
var person = {
  name: ['Bob', 'Smith'],
  age: 32,gender: 'male',
  interests: ['music', 'skiing'],
  bio: function() {
    alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes 
    ' + this.interests[0] + ' and ' + this.interests[1] + '.');
  },
  greeting: function() {
    alert('Hi! I\'m ' + this.name[0] + '.');
  }
};
  • 使用物件: Dot notation
person.age
//result: 32
person.interests[1]
//result: male
person.bio()
//result: Bob Smith is 32 years old. He likes music and skiing.
  • This: 可以使用物件自己裡面的屬性,不會混到別的物件裡面的屬性

Constructor 和 Object Instances

  • Constructor: 建立一個空的物件架構
  • Instances: 以 constructor 的架構建立物件
    //constructor
    function Person(first, last, age, gender, interests) {
    
      this.name = {
        first,last
      };this.age = age;this.gender = gender;this.interests = interests;this.bio = function() {
        alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' +     this.interests[0] + ' and ' + this.interests[1] + '.');
      };this.greeting = function() {
        alert('Hi! I\'m ' + this.name.first + '.');
      };
    
    };
    // Instances
    var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
    
  • The constructor property
    \\ example
    person1.constructor.name
    \\ result: Person
    

portotype

觀念
觀念

  1. 建立物件的 constructor 時候,把方法寫在 construtor 外面
    function Person(first, last, age, gender, interests) {
    
      this.name = {
        first,last
      };this.age = age;this.gender = gender;this.interests =     interests;
    
    };
    Person.prototype.greeting = function() {
    
      alert('Hi! I\'m ' + this.name.first + '.');
    
    };
    
  2. 修改,新增 prototype 時:新增 farewell 方法
    Person.prototype.farewell = function() {
    
      alert(this.name.first + ' has left the building. Bye for     now!');
    
    }
    
  3. 最後,未來在建立物件時,遵照以下的樣式
    // Constructor with property definitions
    
    function Test(a, b, c, d) {
    
      // property definitions
    
    };
    
    // First method definition
    
    Test.prototype.x = function() { ... }
    
    // Second method definition
    
    Test.prototype.y = function() { ... }
    

Inheritance in JavaScript

狀況:希望建立 Teacher 的 constructor: 1. 利用 Person 已經建立的 constructor 2. 新增屬性與方法建立 Teacher

  1. Person
    function Person(first, last, age, gender, interests) {
    
      this.name = {
        first,last
      };this.age = age;this.gender = gender;this.interests =     interests;
    
    };
    Person.prototype.greeting = function() {
    
      alert('Hi! I\'m ' + this.name.first + '.');
    
    };
    
  2. 建立 Teacher 的 constructor
    function Teacher(first, last, age, gender, interests, subject) {
    
      Person.call(this, first, last, age, gender, interests);
    
      this.subject = subject;
    
    }
    

問題:當我們建立 Person 物件時 var person1 = new Person(),我們如何建立 var person2 = new Teacher() 的情況?

  1. Object.create: 建立一個與 Person.prototype 相同的架構
    Teacher.prototype = Object.create(Person.prototype);
    
  2. Teacher 的 constructor 名為 Teacher
    Teacher.prototype.constructor = Teacher;
    
  3. 測試結果
    Teacher.prototype.constructor//result: Teacher()
    
  4. 修改 Teacher 的 greeting 方法
    Teacher.prototype.greeting = function() {
      var prefix;
    
      if (this.gender === 'male' || this.gender === 'Male' ||     this.gender === 'm' || this.gender === 'M') {
        prefix = 'Mr.';
      } else if (this.gender === 'female' || this.gender ===     'Female' || this.gender === 'f' || this.gender === 'F') {
        prefix = 'Mrs.';
      } else {
        prefix = 'Mx.';
      }
    
      alert('Hello. My name is ' + prefix + ' ' + this.name.last +     ', and I teach ' + this.subject + '.');
    };
    

Working with JSON data

JSON Data Struture:

{
  "squadName" : "Super hero squad",
  "homeTown" : "Metro City",
  "formed" : 2016,
  "active" : true,
  "members" : [
    {
      "name" : "Molecule Man",
      "age" : 29,
      "secretIdentity" : "Dan Jukes",
      "powers" : [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name" : "Madame Uppercut",
      "age" : 39,
      "secretIdentity" : "Jane Wilson",
      "powers" : [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
  ]
}

Loading JSON

  1. store the URL of the JSON file: requestURL
  2. create a request
  3. open a new request using the open() method
  4. setting the responseType to JSON, and sending the request with the send()
  5. waiting for the response to return from the server
// 1
var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json'; 
//2
var request = new XMLHttpRequest();
// 3
request.open('GET', requestURL);
// 4
request.responseType = 'json';
request.send();
// 5
request.onload = function() {
        var superHeroes = request.response;
        populateHeader(superHeroes);
        showHeroes(superHeroes);
    }

Using JSON data

function populateHeader(jsonObj) {
            var myH1 = document.createElement('h1');
            myH1.textContent = jsonObj['squadName'];
            header.appendChild(myH1);

            var myPara = document.createElement('p');
            myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
            header.appendChild(myPara);
        } 

practice

MDN practice

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Bouncing balls</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <h1>
        <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_building_practice" target="_blank">
        bouncing balls
        </a>
    </h1>
    <canvas></canvas>

    <script src="main.js"></script>
</body>

</html>
html,
body {
    margin: 0;
}

html {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    height: 100%;
}

body {
    overflow: hidden;
    height: inherit;
}

h1 {
    font-size: 2rem;
    letter-spacing: -1px;
    position: absolute;
    margin: 0;
    top: -4px;
    right: 5px;
    color: transparent;
    text-shadow: 0 0 4px white;
}
    // setup canvas

    var canvas = document.querySelector('canvas');
    var ctx = canvas.getContext('2d');

    var width = canvas.width = window.innerWidth;
    var height = canvas.height = window.innerHeight;

    // function to generate random number

    function random(min, max) {
        var num = Math.floor(Math.random() * (max - min)) + min;
        return num;
    }

    function Ball(x, y, velX, velY, color, size) {
        this.x = x;
        this.y = y;
        this.velX = velX;
        this.velY = velY;
        this.color = color;
        this.size = size;
    }

    Ball.prototype.draw = function() {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
        ctx.fill();
    }

    var testBall = new Ball(50, 100, 4, 4, 'blue', 10);
    testBall.x;
    testBall.size;
    testBall.color;
    testBall.draw();

    Ball.prototype.update = function() {
        if ((this.x + this.size) >= width) {
            this.velX = -(this.velX);
        }

        if ((this.x - this.size) <= 0) {
            this.velX = -(this.velX);
        }

        if ((this.y + this.size) >= height) {
            this.velY = -(this.velY);
        }

        if ((this.y - this.size) <= 0) {
            this.velY = -(this.velY);
        }

        this.x += this.velX;
        this.y += this.velY;
    }

    Ball.prototype.collisionDetect = function() {
        for (var j = 0; j < balls.length; j++) {
            if (!(this === balls[j])) {
                var dx = this.x - balls[j].x;
                var dy = this.y - balls[j].y;
                var distance = Math.sqrt(dx * dx + dy * dy);

                if (distance < this.size + balls[j].size) {
                    balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')';
                }
            }
        }
    }
    var balls = [];

    function loop() {
        ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
        ctx.fillRect(0, 0, width, height);

        while (balls.length < 25) {
            var ball = new Ball(
                random(0, width),
                random(0, height),
                random(-7, 7),
                random(-7, 7),
                'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) + ')',
                random(10, 20)
            );
            balls.push(ball);
        }

        for (var i = 0; i < balls.length; i++) {
            balls[i].draw();
            balls[i].update();
            balls[i].collisionDetect();
        }

        requestAnimationFrame(loop);
    }

    loop();

上一篇
A Javascript library: jQuery (w3school)
下一篇
ColdFusion: ColdFusion MX 網站威力實作 part1
系列文
網頁服務開發之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言