国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript - 變量、值、類型

ziwenxie / 2052人閱讀

摘要:一返回值共有種二變量聲明方法聲明一個變量,可以將其初始化為一個值聲明一個塊級作用域變量,可以將其初始化一個值聲明一個只讀的常量使用的注意事項不支持塊級作用域存在變量提升舉例由于變量聲明提升,這段代碼相當于使用的注意事項塊級作用域

一、type of

返回值共有7種:undefined, object, boolean, number, string, symbol, function

typeof undefined === "undefined";
typeof true === "boolean";
typeof 123 === "number";
typeof "username" === "string";
typeof {team : "75team"} === "object"
typeof symbol() === "symbol";
typeof null === "object";
typeof function() {} === "function";
二、變量聲明方法

var - 聲明一個變量,可以將其初始化為一個值
const - 聲明一個塊級作用域變量,可以將其初始化一個值
let - 聲明一個只讀的常量

2.1 使用var的注意事項:

var不支持塊級作用域

var存在變量提升

舉例:

console.log(a === undefined);
var a = 10;

function foo(){
  console.log([a, i]);
  var a = 20;
  for(var i = 0; i < a; i++){
    //do sth.
  }
  console.log([a, i]);
}
foo();
//---console:
true
[undefined, undefined]
[20, 20]

由于變量聲明提升,這段代碼相當于

var a;
console.log(a === undefined);
a = 10;

function foo(){
  var a, i;
  console.log([a, i]);
  a = 20;
  for(i = 0; i < a; i++){
    //do sth.
  }
  console.log([a, i]);
}
foo();
2.2 使用let的注意事項

塊級作用域

同一個作用域下只能聲明一次

暫存死區(temporal dead zone)

循環中的let作用域

瀏覽器兼容性

塊級作用域示例:

{
  let x = 10;

  console.log("x is " + x);
}

console.log(typeof x);

let i = 20;

for(let i = 0; i < 10; i++){
  console.log(i);
}
console.log(i);

var y = 3;
var y = 4;

console.log(y);

// let z = 3;
// var z = 4;
// console.log(z);
//---console:

"x is 10"
"undefined"
0
1
2
3
4
5
6
7
8
9
20
4

暫存死區示例:

let x = 10;

function foo(){
  console.log(x);
  let x = 20;  //如果這一句改成 var 會怎樣?
  return x * x;
}

console.log(foo());
//---console:
"ReferenceError: x is not defined"

循環中的let作用域示例:

var buttons = document.querySelectorAll("button");

for(var i = 0; i < buttons.length; i++){
  buttons[i].onclick = evt => console.log("點擊了第 " + i + "個按鈕");
}
//---console:
"點擊了第 5個按鈕"
"點擊了第 5個按鈕"
"點擊了第 5個按鈕"
"點擊了第 5個按鈕"
這里是因為click這個方法是異步的,只有在點擊之后,js才會去執行這段代碼,這時for循環中的 i 已經循環完,所以會產生點擊哪個按鈕都返回 5 。解決這類問題常利用‘閉包’,或者使用let
var buttons = document.querySelectorAll("button");

for(var i = 0; i < buttons.length; i++){
  (function (i) {
       buttons[i].onclick = evt => console.log("點擊了第 " + i + "個按鈕");
  })(i)
}
2.2 使用const的注意事項

const聲明的變量不可以再次被改變

其他使用與let一樣

示例:

const BUFFER_SIZE = 1024;

let buffer = new ArrayBuffer(BUFFER_SIZE);

console.log(buffer);

let data = new Uint16Array(buffer);
let data2 = new Uint8Array(buffer);

data[0] = 0xff06;

console.log(data2[0], data2[1]);
//---console:
[object ArrayBuffer]
6
255

注意:給變量賦值為對象時,對象引用不能變,但是對象里的屬性值可以改變。

// A的地址沒有改變,這樣也是可以的。
const A = {a: 1};
A.a = 2;
console.log(A); 
// A: {a: 2}

// 如何不讓A被操作呢?
const A = Object.freeze({a: 1});
A.a = 2;
console.log(A); 
// A: {a: 1}
三、嚴格模式-"use strict";
(function(){
  //"use strict";
  
  var x = y = 0;
  
  //do sth.
})();

console.log([typeof x, typeof y]);
//---console:
["undefined", "number"]

但是在ES6與‘use strict’某些時候會有沖突

(function f( j = 777 ) {
    "use strict";
    // do sth.
})


ERROR: Uncaught SyntaxError: Illegal "use strict" directive in function with non-simple parameter list
四、抽象相等 4.1嚴格相等于非嚴格相等

javascript

console.log([null !== undefined, null == undefined]); //true, true

console.log(["1" == 1, [] == 0, "" == 0, 0 == false, 1 == true]);

console.log([NaN != NaN]);

Console

[true, true]
[true, true, true, true, true]
[true]
五、Boolean 類型

true 和 false

0、""、null、undefined 被隱式轉換為 false,其他轉為 true

建議采用嚴格比較,可以通過 !! 將非 boolean 值轉為 boolean

布爾操作符 && 和 || 并不會轉換類型

&& 和 || 的短路特性

比較操作符總是返回 boolean 類型

5.1 Boolean類型的應用

javascript

var result = 1 && 2;

console.log([result, !!result]);

var list = [1,,2,,,4,5,0,9];

list = list.filter(item => item);

console.log(list);

function showTip(tip){
  tip = tip || "This is a tip";
  console.log(tip);
  
  var label = document.createElement("label");
  label.className = "tip";
  label.innerHTML = tip;
  
  document.body.appendChild(label);
}

document.querySelector("button").onclick 
  = showTip.bind(null, "");

console

"This is a tip"
"This is a tip"
"This is a tip"
...

示例2:
JavaScript

/**
 * options -> type:x、y、xy or function
 */
function applyAnimate(el, duration, options, easing){
  var startTime = Date.now();
  if(typeof el === "string"){
    el = document.querySelector(el);
  }
  duration = duration || 1000;
  options = options || {
    property: "x",
    distance: 100
  };
  easing = easing || function(p){return p;};

  requestAnimationFrame(function update(){
    var now = Date.now();
    var p = (now - startTime)/duration;
    var ep = easing(p); 

    if(typeof options !== "function"){
      var attr = options.property, distance = options.distance;
      var translate = [];
      if(attr.indexOf("x") >= 0){
        translate.push("translateX(" + distance * ep + "px)");
      }
      if(attr.indexOf("y") >= 0){
        translate.push("translateY(" + distance * ep + "px)");
      }
      el.style.transform = translate.join(" ");
    }else{
      options(el, ep, p);
    }
    
    if(p <= 1){
      requestAnimationFrame(update);
    }
  });
}

document.querySelector(".ball").onclick = function(){

  applyAnimate(".ball");

  /*applyAnimate(".ball", 1000, function(el, ep, p){
  const distance = 100, pi2 = 2 * Math.PI;
  el.style.transform = "translate(" + distance * Math.cos(pi2 * ep) 
    + "px," + distance * Math.sin(pi2 * ep)  + "px)";
});*/
}
六、Number

整數 -2^53 ~ 2^53

小數精度 Number.EPSILON

Infinity、Number.MAX_VALUE、Number.MIN_VALUE

浮點數有精度問題

2進制,8進制,十六進制

+0和-0

6.1 Number類型的應用

javascript

//-----------

console.log(0.2 + 0.4); //WTF!! IEEE754

console.log(((0.2 + 0.4) * 100).toPrecision(2));

console.log(((0.2 + 0.4) * 100).toFixed(2));

//----------

const ball = document.getElementById("ball");

var distance = 100, duration = 2000;

ball.onclick = function(){
  var startTime = Date.now();
  requestAnimationFrame(function update(){
    var p = (Date.now() - startTime) / duration;
  
    ball.style.transform = "translateX(" + distance * p + "px)"
    console.log(p,distance);
    if(p <= 1){ //不應當用相等比較浮點數!!
      requestAnimationFrame(update);
    }
  });
}

console

0.6000000000000001
"60"
"60.00"

示例2:
JavaScript

console.log([Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER]);

var bigInteger = Number.MAX_SAFE_INTEGER + 1;

console.log([bigInteger, bigInteger + 1, bigInteger + 2]); //WTF!!

console.log(1234567890000000000000000000); //科學計數法

console.log(Math.pow(2, 53) === bigInteger);

console.log([Number.isSafeInteger(bigInteger), 
             Number.isSafeInteger(bigInteger - 1)]);

//-----------

console.log([Number.MAX_VALUE, Number.MIN_VALUE]);

console.log([Number.MAX_VALUE + 1, Number.MAX_VALUE * 2]);

console.log([Number.EPSILON]);

console.log(0.99 - 1e-17 === 0.99);

console.log(0.99 - Number.EPSILON === 0.99);

console

[9007199254740991, -9007199254740991]
[9007199254740992, 9007199254740992, 9007199254740994]
1.23456789e+27
true
[false, true]
[1.7976931348623157e+308, 5e-324]
[1.7976931348623157e+308, Infinity]
[2.220446049250313e-16]
true
false
七、String

引號規范

轉義字符

字符串與字符

字符串與類型轉換

常用字符串操作

模板字符串

7.1 引號規范與轉義

javascript

var text = "This is a text."; //規范建議默認使用雙引號
var html = "

This is a paragraph

"; console.log(text); console.log(html); var text2 = "我所做的餡餅 是全天下 最好吃的"; console.log(text2); var text3 = "if(a){ console.log(b); }"; console.log(text3); var text4 = "u5947u821eu56e2"; console.log(text4);

Console

"This is a text."
"

This is a paragraph

" "我所做的餡餅 是全天下 最好吃的" "if(a){ console.log(b); }" "奇舞團"
7.2 處理字符

JavaScript

var str = "my string";

console.log(str.charAt(5));

var charArray = Array.from(str); //str.split("");

console.log(charArray);

console.log(str.charCodeAt(5), str.charCodeAt(6));

console.log(String.fromCharCode(114, 105));

console.log(String.fromCharCode(...charArray.map(c=>c.charCodeAt(0))));

Console

"r"
["m", "y", " ", "s", "t", "r", "i", "n", "g"]
114
105
"ri"
"my string"
7.3 字符串類型轉換 7.3.1 隱式類型轉換
console.log([1+2, "1"+2, "1"-2]); 
// console: [3, "12", -1]
// 注釋:減法不會發生隱式類型轉換,可以用減零的方式將字符串轉化成數字,如:console.log("1"- 0 + 2);
console.log(parseInt("100abc", 2), Number("0b100")); 
// console: 4 4 
// 轉整數
console.log(parseFloat("12.3e10xx")); 
// console: 123000000000
// 轉浮點數, parseFloat會盡可能的將字符串中的值轉化成浮點數,然后將轉化不了的字符串忽略,這里是將“xx”省略。
// 封裝對象的 toString 方法
var foo = {
  toString(){
   return "foo"; 
  }
};

console.log(foo + " bar");
// console: "foo bar"
7.5 常用字符串操作

javascript

const a = "hello";
const b = "WORLD";
const c = "!";

console.log(a + " " + b + c); //字符串連接
// 注釋:字符串可以用“+”相加,但在某些瀏覽器內性能不好,可采用數組的join方法拼接字符串。
// console.log([a, b, c].join(""));

console.log(a.toUpperCase() + " " + b.toLowerCase() + c); //轉大小寫

console.log(a.split("").reverse().join("")); //逆序字符串

console.log([a.slice(2,3), a.substr(2,3)]); //截取子串
// 注釋: slice和substr的參數含義不一樣

const d = a + " " + b + c;

console.log(d.indexOf(b)); //字符串查找

console.log(d.replace(a, a.toUpperCase()));

Console

"hello WORLD!"
"HELLO world!"
"olleh"
["l", "llo"]
6
"HELLO WORLD!"
7.6 模板字符串(ES6)
const tpl1 = `我所做的餡餅
  是全天下
  最好吃的`;

console.log([tpl1, typeof tpl1]);

{
  let who = "月影", what = "月餅";
  
  const tpl2 = `${who}所做的${what}
    是全天下
    最好吃的`;

  console.log(tpl2);
}
["我所做的餡餅
  是全天下
  最好吃的", "string"]
"月影所做的月餅
    是全天下
    最好吃的"
7.7 模板字符串高級用法

JavaScript

let output = (a, b) => `${a} + ${b} is ${a + b}`;

console.log(output(3, 5));

let formatedList = (data) => `
  
    ${data.map(item=>`
  • 姓名:${item.name}年齡:${item.age}
  • `).join("")}
`; let data = [ {name: "Akira", age: 35}, {name: "Jane", age: 26}, {name: "Jhon", age: 54} ]; console.log(formatedList(data));

Console

"3 + 5 is 8"
"
  
  • 姓名:Akira年齡:35
  • 姓名:Jane年齡:26
  • 姓名:Jhon年齡:54
"
八、Object

對象的屬性

值和引用

類型與構造器

內置類型

對象的高級屬性

class

8.1 對象的屬性

屬性名規則:可以是有效字符串或者任意可轉換為有效字符串的類型???????

屬性的訪問和遍歷???????

8.2 對象創建
//創建對象
{
  let myObj = new Object();

  myObj.name = "akira";
  myObj.birthday = "12-29";

  console.log(myObj);
}

//然而上面這么寫的是菜鳥,普通青年這么寫
{
  let myObj = {
    name: "akira",
    birthday: "12-29"
  };
  
  console.log(myObj);
}

//有些二逼青年:
{
  let myObj = Object.create({name: "akira", birthday: "21-29"});
  
  console.log(myObj);
}
8.3 屬性訪問

javascript

// 對象屬性是有效字符串,屬性訪問可以通過.和[]
{
  let myObj = {
    name: "akira",
    birthday: "12-29"
  };

  console.log([myObj.name, myObj["birthday"]]);
}

{
  // []屬性訪問的好處是可以計算
  const conf = {
    adapter: "sqlite",
    db: {
      sqlite: {
        //...
      },
      mysql: {
        //...
      }
    }
  }
  let dbSetting = conf.db[conf.adapter];
}

{
  // 在 ES6 中字面量的 key 也支持屬性計算
  // 比如可以給對象定義一個變量key
  let process = {env: {}};

  const ENV = process.env.JSBIN_ENV || "development";
  const conf = {
    [ENV]: true
  };

  console.log([conf.development, conf.production]);


  //ES5中只能這樣實現:
  var ENV = process.env.JSBIN_ENV || "development";
  var conf = {};
  conf[ENV] = true; 
  console.log([conf.development, conf.production]);
}

Console

["akira", "12-29"]
[true, undefined]
8.4 屬性訪問

javscript

let point = {
  x : 100,
  y : 100,
  getLength : function(){
    let {x, y} = this;
    return Math.sqrt(x * x + y * y);
  }
}

console.log(point.getLength());

//用 for...in 遍歷
for(let key in point){
  console.log([key, point[key]]);
}

//用 Object.keys 遍歷
Object.keys(point).forEach((key) => console.log([key, point[key]]));

Console

141.4213562373095
["x", 100]
["y", 100]
["getLength", function(){
  let {x, y} = this;
  return Math.sqrt(x * x + y * y);
}]
["x", 100]
["y", 100]
["getLength", function(){
  let {x, y} = this;
  return Math.sqrt(x * x + y * y);
}]
8.5 值和引用

值類型與引用類型

基本類型對應的包裝類型

對象的拷貝

let x = 20, y = 30;

function foo(a, b){
  a++;
  b++;
  console.log([a, b]);
}

foo(x, y);

console.log([x, y]);
// 注意:Number是值類型,當把x,y作為參數傳遞給function的時候,只是傳遞了x,y的副本,所以執行完foo(x,y), x,y的值并沒有變化。

const obj = {x: 20, y: 30};

function foo2(obj){
  obj.x++;
  obj.y++;
  console.log(obj);
}

foo2(obj);

console.log(obj);
// 注意:Object是引用類型,它是將obj里的引用自加,所以函數執行完,obj里的值會發生變化。

Console

[21, 31]
[20, 30]
[object Object] {
  x: 21,
  y: 31
}
[object Object] {
  x: 21,
  y: 31
}
九、基本類型的包裝類
var str = "Hello World";
var strObj = new String(str);
// 注釋:如果寫new是包裝類型,如果不寫new是值類型

console.log([str, strObj]); 
// console: ["Hello World", "Hello World"]

console.log([typeof str, typeof strObj]);
// console: ["string", "object"]

console.log([str instanceof String, strObj instanceof String]);
// console: [false, true]

var n = new Number(10);
console.log([typeof n, typeof ++n]);
// console: ["object", "number"]

console.log(Object.prototype.toString.call(10));
// console: [object Number]
十、對象的拷貝
let conf = {
  adapter: "sqlite",
  db: {
    sqlite: {
      name: "xxx.sqlite"
    },
    mysql: {
      name: "xxx",
      username: "work",
      passwd: "******"
    }
  }
};

//直接引用
let conf2 = conf;
conf2.adapter = "mysql";

console.log(conf.adapter);
// console: "mysql"

//ES5 淺拷貝
conf.adapter = "sqlite";
let copied = Object.assign({}, conf);
copied.adapter = "mysql";

console.log(conf.adapter);
// console: "sqlite"
console.log(copied.adapter);
// console: "mysql"
copied.db.sqlite.name = "yyy.sqlite";
console.log(conf.db.sqlite.name);
// console: "yyy.sqlite"

//深拷貝
function deepCopy(des, src){
  for(var key in src){
    let prop = src[key];
    if(typeof prop === "object"){
      des[key] = des[key] || {};
      deepCopy(des[key], prop);
    }else{
      des[key] = src[key];
    }
  }
  return des;
}

let deepCopied = deepCopy({}, conf);
deepCopied.db.sqlite.name = "zzz.sqlite";

console.log([deepCopied.db.sqlite.name, conf.db.sqlite.name]);
// console: ["zzz.sqlite", "yyy.sqlite"]
十一、對象的類型和構造器

new 和 constructor

prototype

instanceOf

ES6 class

//假設 JS 沒有 "new" 操作符,我們該如何實現創建對象?
function defineClass(initializer, proto){  
  return function f(...args){
    let obj = Object.create(proto);
    //f.prototype = proto; //just let instanceof make sense    
    obj.constructor = initializer;
    obj.constructor(...args);
    return obj;
  }
}

var Point = defineClass(function(x, y){
  this.x = x;
  this.y = y;
}, {
  getLength: function(){
    let {x, y} = this;
    return Math.sqrt(x * x + y * y);
  }
});

var p = Point(3, 4);
console.log([p.getLength(), p instanceof Point, p instanceof Object]);

//所以 "new" 其實是一種語法糖
十二、原型鏈
// __proto__ 暴力構建原型鏈
var a = {x : 1}, 
    b = {y : 2}, 
    c = {z : 3};
    
b.__proto__ = a;
c.__proto__ = b;

console.log(c);

/**
 * console:
 * [object Object] {
 *   x: 1,
 *   y: 2,
 *   z: 3
 * }
 */
//使用 Object.create 構建原型鏈
var a = {x : 1};
var b = Object.create(a); // b繼承對象a
b.y = 2;
var c = Object.create(b); // c繼承對象b
c.z = 3;

console.log(c);
/**
 * console:
 * [object Object] {
 *   x: 1,
 *   y: 2,
 *   z: 3
 * }
 */
//使用構造器方式
function A() {
  this.x = 1;
}

function B() {
  this.y = 2;
}
B.prototype = new A();

function C() {
  this.z = 3;
}
C.prototype = new B();

var c = new C();
console.log(c);
/**
 * console:
 * [object Object] {
 *   x: 1,
 *   y: 2,
 *   z: 3
 * }
*/

12.1 原型鏈有什么弊端?

設計原型鏈是為了代碼復用,但是原型鏈有額外構造器調用的問題。

12.2 問題:額外的構造器調用?

javascript

//原型繼承
/**
 * abstract point
 */
function Point(components){
  console.log("Point constructor called");
  this.components = components;
}

Point.prototype = {
  getDimension: function(){
    return this.components.length;
  },
  getLength: function(){
    var sum = 0, components = this.components;
    for(var i = 0; i < components.length; i++){
      sum += Math.pow(components[i], 2);
    }
    return Math.sqrt(sum);
  }
};

function Point2D(x, y){
  Point.call(this, [x, y]);
}

Point2D.prototype = new Point();

Point2D.prototype.getXY = function(){
  var components = this.components;
  return {
    x: components[0],
    y: components[1]
  };
}

Console

"Point constructor called"
"Point constructor called"
["(3,4)", 5, true]
// 注意:這里調用了兩次構造器
解決方法 1:通用化父類構造器
//原型繼承
/**
 * abstract point
 */
function Point(dimension){
  console.log("Point constructor called");
  this.dimension = dimension;
}

Point.prototype = {
  setComponents: function(){
    components = [].slice.call(arguments);
    if(this.dimension !== components.length){
      throw new Error("Dimension not match!");
    }
    this.components = components;
  },
  getDimension: function(){
    return this.dimension;
  },
  getLength: function(){
    var sum = 0, components = this.components;
    for(var i = 0; i < components.length; i++){
      sum += Math.pow(components[i], 2);
    }
    return Math.sqrt(sum);
  }
};

function Point2D(x, y){
  this.setComponents(x, y);
}

Point2D.prototype = new Point(2);

Point2D.prototype.getXY = function(){
  var components = this.components;
  return {
    x: components[0],
    y: components[1]
  };
}

Point2D.prototype.toString = function(){
  return "(" + this.components + ")";
}

var p = new Point2D(3, 4);

console.log([p+"", p.getLength(), p instanceof Point]);

Console

"Point constructor called"
["(3,4)", 5, true]

注釋:但這并不總是好的,尤其是在多重繼承的時候

解決方法 2:延遲父類構造器調用
//原型繼承
/**
 * abstract point
 */
function Point(components){
  console.log("Point constructor called");
  this.components = components;
}

Point.prototype = {
  getDimension: function(){
    return this.components.length;
  },
  getLength: function(){
    var sum = 0, components = this.components;
    for(var i = 0; i < components.length; i++){
      sum += Math.pow(components[i], 2);
    }
    return Math.sqrt(sum);
  }
};

function Point2D(x, y){
  Point.call(this, [x, y]);
}

Point2D.prototype = Object.create(Point.prototype);
//function PointT(){};
//PointT.prototype = Point.prototype;
//Point2D.prototype = new PointT();

Point2D.prototype.getXY = function(){
  var components = this.components;
  return {
    x: components[0],
    y: components[1]
  };
}

Point2D.prototype.toString = function(){
  return "(" + this.components + ")";
}

var p = new Point2D(3, 4);

console.log([p+"", p.getLength(), p instanceof Point]);

Console

"Point constructor called"
["(3,4)", 5, true]
十三、javascript內置類型

Object

Function

Array

Date

Regex

Error

Math

ArrayBuffer

Promise

DataView

Map

Set

TypedArray // Uint16Array(buffer) Uint8Array(buffer)

Proxy(ES6)// 處理異步

十四、為什么不建議修改 Object.prototype 和 Array.prototype 14.1 在數組上添加方法會被for...in枚舉出來
Array.prototype.remove = function(item) {
  var idx = this.indexOf(item);
  if(idx >= 0){
    return this.splice(idx, 1)[0];
  }
  return null;
}

var arr = [1, 2, 3];
arr.remove(2);  //perfect??
console.log(arr);

for(var i in arr){
  if(!Number.isNaN(i-0)){
    console.log(i + ":" + arr[i]);
  }else{
    console.log(i + "是什么鬼?");
  }
}

/**
 * [1, 3]
 * "0:1"
 * "1:3"
 * "remove是什么鬼?"
 */
 
 // 注釋:利用for in遍歷數組或對象的好處是可以把值為undefined的過濾掉,它會把數組上可枚舉的屬性都遍歷出來。
解決這一問題的方法

使用 ES5 新特性 defineProperty

規定禁止使用 for...in 操作數組,只用 for 或 Array.prototype.forEach

規定禁止往數組上隨便添加方法

示例:

Object.defineProperty(Array.prototype, "remove", {
  value : function(item) {
    var idx = this.indexOf(item);
    if(idx >= 0) {
      return this.splice(idx, 1); 
    }
    return null;  
  },
  // enumerable: true 
  // 當且僅當該屬性的enumerable為true時,該屬性才能夠出現在對象的枚舉屬性中。默認為 false。
});

var arr = [1, 2, 3];
arr.remove(2);
console.log(arr);

for(var i in arr) {
  if(!Number.isNaN(i-0)) {
    console.log(i + ":" + arr[i]);
  }else{
    console.log(i + "是什么鬼?");
  }
}

/** 
 * console:
 * [1, 3]
 * "0:1"
 * "1:3"
 */
14.2 getter / setter
function Point2D(x, y){
  this.x = x;
  this.y = y;
}

Object.defineProperty(Point2D.prototype, "length", {
  get: function() {
    let {x, y} = this;
    return Math.sqrt(x * x + y * y);
  },
  set: function(len) {
    let arc = Math.atan2(this.y, this.x);
    this.x = len * Math.cos(arc);
    this.y = len * Math.sin(arc);
  }
});

Object.defineProperty(Point2D.prototype, "arc", {
  get: function(){
    let {x, y} = this;
    return 180 * Math.atan2(y, x) / Math.PI;
  },
  set: function(arc){
    arc = Math.PI * arc / 180;
    let len = this.length;
    this.x = len * Math.cos(arc);
    this.y = len * Math.sin(arc);
  }
});

let p = new Point2D(1, 1);

console.log([p.length, p.arc]);
// [1.4142135623730951, 45]

p.length *= 2;

console.log([p.x, p.y]);
// [2.0000000000000004, 2]

p.arc = 90;
console.log([p.x, p.y]);
// [1.7319121124709868e-16, 2.8284271247461903]
14.3 雙向綁定
const view = {
  nameEl: document.getElementById("name"),
  ageEl: document.getElementById("age"),
  submitBtn: document.getElementById("confirm")
}

view.submitBtn.addEventListener("click", function(evt){
  console.log("你要提交的數據是:" + [user.name, user.age]);
  evt.preventDefault();
});

function User(name, age){
  this.name = name;
  this.age = age;
}

User.prototype.bind = function(view){
  view.nameEl.addEventListener("change", evt => {
     this.name = evt.target.value;
  });
  view.ageEl.addEventListener("change", evt => {
     this.age = evt.target.value;
  });
}

Object.defineProperty(User.prototype, "name", {
  set: function(name){
    view.nameEl.value = name;
  },
  get: function(){
    return view.nameEl.value;
  }
});

Object.defineProperty(User.prototype, "age", {
  set: function(name){
    var ageOptions = Array.from(view.ageEl.options)
              .map(item => item.innerHTML);
    if(ageOptions.indexOf(name) === "-1"){
      throw new Error("無效的年齡格式");
    }
    view.ageEl.value = name;
  },
  get: function(){
    return view.ageEl.value;
  }
});

var user = new User("akira", "80后");
user.bind(view);

演示 demo

歡迎關注

文章內容來源:360奇舞團前端星課程。

奇舞周刊: https://weekly.75team.com/

博客:

奇舞團博客:https://75team.com/

月影的博客:https://www.h5jun.com/

屈屈的博客:https://imququ.com/

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98220.html

相關文章

  • JavaScript學習第一天筆記(變量、常量、數據類型

    摘要:變量與常量變量定義變量是存儲數據信息的容器。中,變量是弱類型,也被稱為松散類型。三類型布爾類型只有兩個值均為小寫如果大寫活著大小寫混合,識別為另一個變量名稱。 JavaScript簡介 JavaScript是一門跨平臺、面向對象的輕量級腳本語言,運行于JavaScript解釋器或者引擎中。JavaScript中,包括三個主要的部分1.核心語法內容(ECMAScript)2.文檔對象模型...

    tinysun1234 評論0 收藏0
  • JavaScript基礎語法 變量 常量 數據類型

    摘要:第十六天筆記基礎語法區分大小寫是一種區分大小寫的語言的關鍵字變量名函數名以及任何其他的標識符必須適應一致的大小寫形勢臥龍前端空格和換行并不是的語法內容可有可無建議使用將代碼書寫的更加整潔美觀更有可讀性可選的分號分號可選項語法并不是強制要 第十六天筆記 JavaScript 基礎語法 區分大小寫 JavaScript是一種區分大小寫的語言 JavaScript的關鍵字 變量名 函...

    xingpingz 評論0 收藏0
  • JavaScript的個人分享

    摘要:的基礎語法的語法是區分大小寫的注意在中是區分大小寫的變量名稱不能是中文代碼示例一花一世界控制臺調用效果圖語法中的空格與換行注意并不是的語法內容可有可無的建議使用因為這樣會使代碼看的更清晰利于閱讀代碼示例代碼一花一世界中的分號可選項語法并 JavaScript的基礎語法: JavaScript的語法是區分大小寫的 注意: 在JavaScript中是區分大小寫的 變量名稱不能是中文 代...

    JasonZhang 評論0 收藏0
  • JavaScript入門

    摘要:被識別為結束符。變量時被認為時有名字的容器。常量一旦被聲明初始化,值并不能被改變。字符串可以看成右字符組成的數組,可能被誤認為可變的。表達式沒有顯示的返回任何內容。 Java script 簡介 Javascript 是一門跨平臺,面向對象的輕量級腳本語言,運行于Javascript解釋權/引擎 avascript內置了一個包含一系列對象的標準庫,比如數組,日期,數字和一個語言元素合...

    AaronYuan 評論0 收藏0
  • JavaScript學習總結(一)基礎部分

    摘要:前綴規范每個局部變量都需要有一個類型前綴,按照類型可以分為表示字符串。例如,表示以上未涉及到的其他對象,例如,表示全局變量,例如,是一種區分大小寫的語言。布爾值與字符串相加將布爾值強制轉換為字符串。 基本概念 javascript是一門解釋型的語言,瀏覽器充當解釋器。js執行時,在同一個作用域內是先解釋再執行。解釋的時候會編譯function和var這兩個關鍵詞定義的變量,編譯完成后從...

    AlanKeene 評論0 收藏0
  • JavaScript 闖關記》之變量和數據類型

    摘要:當程序需要將值保存起來以備將來使用時,便將其賦值給一個變量,值的類型稱作數據類型。運算符鑒于是松散類型的,因此需要有一種手段來檢測給定變量的數據類型,就是負責提供這方面信息的運算符。 當程序需要將值保存起來以備將來使用時,便將其賦值給一個變量,值的類型稱作數據類型。 變量 JavaScript 的變量是松散類型的,所謂松散類型就是可以用來保存任何類型的數據。換句話說,每個變量僅僅是一個...

    HackerShell 評論0 收藏0

發表評論

0條評論

ziwenxie

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<