edoo
9/25/2017 - 9:38 AM

你平常不會用到的js

你平常不會用到的js

str1 = "http://www.google.tw/search?q=中文";
obj = {
    get a(){return '1';},
    set b(value){this.c = value;},
    c:1
};
class Cls{
    constructor(name){
        console.log("hello",name);
        if (typeof(new.target)==='function')
            new.target()
    }
}
//symbol([String]) 作為key或event的索引
symbol=Symbol('symbol string')
obj[symbol]='hello world'
console.log(obj[symbol])                                                        //'hello world'

// for (key in obj){console.log(key)}                                           // 遍歷obj的key 
for (key in obj) console.log(key);                                              //a b c
for (key in ['1', 2]) console.log(key);                                         //0 1
// for (value of array){console.log(value)}                                     //遍歷array的value
for (value of ['1', 2]) console.log(value);                                     //'1' 2
// Object.keys(obj)                                                             // 回傳Array,值為obj的key
Object.keys(obj)                                                                //['a', 'b','c']
// Object.values(obj)                                                           // 回傳Array,值為obj的value
Object.values(obj)                                                              //[ '1', undefined, 1 ]
// Object.entries(obj)                                                          // 回傳Array,值為obj的[key,value]
Object.entries(obj)                                                             //[ [ 'a', '1' ], [ 'b', undefined ], [ 'c', 1 ] ]
// Object.getOwnPropertyDescriptors(obj)                                        //返回obj 所有屬性特性值
Object.getOwnPropertyDescriptors(obj)                                           //{ a:{ get: [Function: get a], set: undefined, enumerable: true, configurable: true }, b:{ get: undefined, set: [Function: set b], enumerable: true, configurable: true }, c: { value: 1, writable: true, enumerable: true, configurable: true }, [Symbol(symbol string)]:{ value: 'hello world', writable: true, enumerable: true, configurable: true } }
// Object.getOwnPropertyDescriptor(obj,attributeName)                           //返回obj 指定屬性特性值
Object.getOwnPropertyDescriptor(obj,'c')                                        //{ value: 1, writable: true, enumerable: true, configurable: true }
// Object.getOwnPropertyNames(obj)                                              //返回所有屬性名稱
Object.getOwnPropertyNames(obj)                                                 //[ 'a', 'b', 'c']
// Object.getOwnPropertySymbols(obj)                                            //返回所有符號
Object.getOwnPropertySymbols(obj)                                               //[ Symbol(symbol string) 
// obj.__lookupGetter__("attributeName")                                        //返回getter函數定義
obj.__lookupGetter__("a")                                                       //"function get a(){return \'1\';}"
// obj.__lookupSetter__("attributeName")                                        //返回setter函數定義
obj.__lookupSetter__("b")                                                       //'function set b(value){this.c=value;}'
// obj.__defineGetter__("attributeName",function(){...})                        // 設定 getter function
obj.__defineGetter__("a",function(){return this.c*2;})                          //
// obj.__defineSetter__("attributeName",function(value){...})                   // 設定 Setter function
obj.__defineSetter__("b",function(value){console.log(value);this.c *= value;})  //
// Object.defineProperty(obj,attribute,property)                                // 設定屬性特性
Object.defineProperty(obj,'b',{enumerable:false})       
Object.keys()                                                                   // ['a', 'c']
// Object.defineProperties(obj,property)                                        // 設定多個屬性特性
Object.defineProperties(obj,{a:{configurable:true},c:{value:20}})
Object.defineProperties(obj,{a:{enumerable:false}})                             // TypeError
console.log(obj.c)                                                              // 20
// Object.setPropertyOf(type,propertys)                                         // 設定原型(好比新增修改靜態屬性方法)
Object.setPrototypeOf(obj,{hello:function(){console.log("world")}})
obj.hello()                                                                  // 'world'
// /* 
//     //defineProperty property              get|set不能與writable|value 同時設置
//     {
//       configurable : boolean,            //可否改變enumerable,configurable,writable的值
//       enumerable : boolean,              //可否使用Object.keys|values|entries 或for ( var in obj )找到它
//       get : function(){return var},      //設定getter函數
//       set : function(value){...},        //設定setter函數
//       writable : boolean,                //可否使用'='設定值(是否可寫)
//       value :var                         //設定值
//     }
// */
// /* 
//     //definePropertys property
//     {
//       "attribute":{
//         configurable : boolean,          //可否改變enumerable,configurable,writable的值
//         enumerable : boolean,            //可否使用Object.keys|values|entries 或for ( var in obj )找到它
//         get : function(){return var},    //設定getter函數
//         set : function(value){...},      //設定setter函數
//         writable : boolean,              //可否使用'='設定值(是否可寫)
//         value :var                       //設定值
//       },
//       ...
//     }
// */

// Object.preventExtensions(obj)            // 不可再擴展(增加屬性)
Object.preventExtensions(obj)
// Object.isExtensible(obj)                 // 是否可擴展
Object.isExtensible(obj)                    // false
// Object.seal(obj)                         // 不可再擴展,不可修改特性
Object.seal(obj)
// Object.isSealed(obj)                     // 是否為不可再擴展,不可修改特性
Object.isSealed(obj)                        // true
// Object.freeze(obj)                       // 不可再擴展,不可修改特性,不可寫入(唯讀之意)
Object.freeze(obj)
// Object.isFrozen(obj)                     // 是否唯讀
Object.isFrozen(obj)                        // true


//bind,call,apply
function f (arg1, arg2) {
  console.log(this.value, arg1, arg2);
}
o1 = {value:1};
o2 = {value:2};
o3 = {value:3};
//bind(obj)                 //產生個新函數,其this為obj
newf = f.bind(o1);
newf(4,5);                  // 1 4 5
f.bind(o1)(4,5);            // 1 4 5
//call(obj,arg)             // 第一個參數為this,爾後依序帶入
f.call(o2,5,6);             // 2 5 6
//f.apply(obj,[arg])        // 第一個參數為this,第二參數為陣列當函數參數
f.apply(o3,[6,7]);          // 3 6 7


// Reflect 像Object 且更多變
// Reflect.apply(function,objthis,[arg])
Reflect.apply(f,o3,[6,7])   // 3 6 7
// Reflect.construct(class, [arg][,function OverwriteNewTarget(){...} ])            //如同 new class(),可複寫 new.target
Reflect.construct(Cls, ['John Cena'] ,function(){console.log('How are you?');});    //Hello John Cena How are you?
// Reflect.defineProperty(obj,'attributeName',property)                             //如 Object.defineProperty , 但返回 true,false,TypeError 而 Object.defineProperty 可能 TypeError
Reflect.defineProperty(obj,'a',{enumerable:false})                                  //false
Object.defineProperty(obj,'a',{enumerable:false})                                   //TypeError
// Reflect.deleteProperty(obj,'attributeName')                                      //如同 delete obj['attributeName'] ,但返回 true,false,TypeError
Reflect.deleteProperty(obj,'a')                                                     //false
// Reflect.get(obj,'attributeName'[,receiver])                                      //取得值
Reflect.get(obj,'a')                                                                //40
// Reflect.getOwnPropertyDescriptor(obj,'attributeName')                            //如同 Object.getOwnPropertyDescriptor ,但可能拋出TypeError
Reflect.getOwnPropertyDescriptor('string','s')                                      //TypeError
Object.getOwnPropertyDescriptor('string','s')                                       //undefined
// Reflect.getPrototypeOf(obj)                                                      //如同 Object.getPrototypeOf ,但可能拋出TypeError
Reflect.getPrototypeOf(obj)                                                         //{ hello: [Function: hello] }
Reflect.getPrototypeOf(1)                                                           //TypeError
// Reflect.has(obj,'attributeName')                                                 //如同 'in' 符號
Reflect.has(obj,'a')==='a' in obj                                                   //true
// Reflect.isExtensible(obj)                                                        //如同Object.isExtensible ,但可能拋出TypeError
Reflect.isExtensible(1)                                                             //TypeError
Object.isExtensible(1)                                                              //false
// Reflect.ownKeys(obj)                                                             //如同Object.keys 不受enumerable影響,symbol也會show
Reflect.ownKeys(obj)                                                                //[ 'a', 'b', 'c', Symbol(symbol string) ]
Object.keys(obj)                                                                    //[ 'a', 'c']
// Reflect.preventExtensions(obj)                                                   //如同Object.preventExtensions 返回true,false,TypeError
Reflect.preventExtensions(obj)                                                      //true
Object.preventExtensions(obj)                                                       //obj
// Reflect.set(obj, 'attributeName', value [, receiver])                            //如同 '=' 符號 返回true,false,TypeError
Reflect.set(obj, 'a', 10)                                                           //false
// Reflect.setPrototypeOf(obj, 'attributeName')                                     //如同 Object.setPrototypeOf 返回 true,false,TypeError
Reflect.setPrototypeOf(1, {})                                                       //TypeError
Object.setPrototypeOf(1, {})                                                        //1



// Proxy 類似hook 的概念
var proxy= new Proxy(obj, {
  get: function (target, key, receiver) {
    console.log("target:", target)
    console.log("key:", key)
    console.log("receiver is this proxy:", receiver===proxy) //true
    console.log("Reflect:", Reflect);
    return Reflect.get(target, key, receiver); //overwrite get,if no return no Reflect then return undefined
  },
  set: function (target, key, value, receiver) {
    console.log("target:", target)
    console.log("key:", key)
    console.log("value:", value)
    console.log("receiver is this proxy:", receiver===proxy)
    console.log("Reflect:", Reflect);
    return Reflect.set(target, key, value, receiver); //overwrite set,if no Reflect then set invalid
  }
})
/* 還可用在
//   //getPrototypeOf
//   //setPrototypeOf
//   //isExtensible
//   //preventExtensions
//   //getOwnPropertyDescriptor
//   //defineProperty
//   //has
//   //deleteProperty
//   //ownKeys
//   //apply
//   //construct
*/


// promise
new Promise (function (resolve, reject) {
  resolve('return1');   //如同 return
  reject('error1');     //如同 throw
}).then(function(arg) { // arg == 'return1'
  console.log(arg);     
  throw('error2'); 
  return 'return2';
}).catch(function(err) { // err == 'error2'
  console.log(err);
})
// return1
// error2


// async
function callme1(time) {
    return Math.random()
  }
function callme2(time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function(){
      resolve(Math.random())
    },time)
  })
}

async function asyncFunc (time) {
    result=await callme1(time)
    console.log(result)                                 // 隨機值
    console.log('ok1')
    result=await callme2(time)                          // 返回Promise所得到的隨機值 而非Promise物件
    console.log('typeof:',typeof(result))
    console.log(result)
    console.log('ok2')
    return "hello world"
}

asy=asyncFunc(3000)
console.log(typeof(asy))                                // async 函數返回 Promise物件
asy.then((result)=>{console.log(result)})               // hello world


// generator
result=[]
function * generator(a) {
  console.log('===start===')
  console.log('a:',a)
  b = yield 1
  console.log('b:',b)
  c = yield 2
  console.log('c:',c)
}
gen=generator("this is a")                              // 代入a變數,返回generator物件,尚未開始執行

console.log('===let go===')
result.push( gen.next() )                               // output:'===start==='  arg:代什麼都無效果
result.push( gen.next("this is b") )                    // 代入b變數
result.push( gen.next("this is c") )                    // 代入c變數
console.log(result)                                     // [{ value: 1, done: false }, { value: 2, done: false }, { value: undefined, done: true }]




// encodeURI(string)                                    // encode ASCII、number、~!()*' .          no encode
encodeURI(str1)                                         // 'http://www.google.tw/search?q=%E4%B8%AD%E6%96%87'
// encodeURIComponent(string)                           // encode ASCII、number、~!()*'@#$&=:/,;?+ no encode
str2=encodeURIComponent(str1)                           // 'http%3A%2F%2Fwww.google.tw%2Fsearch%3Fq%3D%E4%B8%AD%E6%96%87'
// decodeURI(string)                                    // decode ASCII、number、~!()*'            no decode
decodeURI(str2)                                         // 'http%3A%2F%2Fwww.google.tw%2Fsearch%3Fq%3D中文'
// decodeURIComponent(string)                           // decode ASCII、number、~!()*'@#$&=:/,;?+ no decode
decodeURIComponent(str2)                                // 'http://www.google.tw/search?q=中文'
//string.padStart(length [, padding])                   //string 使用 padding 填充字串開頭使 string.lenght==length, 預設padding==' '
str1.padStart(39)                                       //'       http://www.google.tw/search?q=中文'
str1.padStart(39,'h')                                   // 'hhhhhhhhttp://www.google.tw/search?q=中文'
str1.padStart(39,'he')                                  // 'hehehehhttp://www.google.tw/search?q=中文'
// string.padEnd(length [, padding])                    //string 使用 padding 填充字串末端使 string.lenght==length, 預設padding==' '
str1.padEnd(39)                                         // '       http://www.google.tw/search?q=中文'
str1.padEnd(39,'h')                                     // 'http://www.google.tw/search?q=中文hhhhhhh'
str1.padEnd(39,'he')                                    // 'http://www.google.tw/search?q=中文heheheh'
// [obj1,obj2,obj3,]                                    // 陣列末端','不報錯
[{a:1},{b:2},{c:3},]                                    // [ { a: 1 }, { b: 2 }, { c: 3 } ]
// [..."string"]                                        // 'string'.split('')
[..."string"]                                           // ["s","t","r","i","n","g"]
// [...[obj1,obj2,obj3]]                                // [obj1,obj2,obj3]
[...[{a:1},{b:2},{c:3}]]                                // [ { a: 1 }, { b: 2 }, { c: 3 } ]


//ArrayBuffer
ab=new ArrayBuffer(12)      
//new [Uint](8|16|32|8)Array(obj: ArrayBuffer)
u8a=new Uint8Array(ab)
u8a[0]=72
u16a=new Uint16Array(u8a.buffer)
u16a[1]=27756
dv=new DataView(u16a.buffer)
dv.setUint16(4,8303,true) //littleEnd
dv.setUint32(6,1466921580)
i16a=new Int16Array(ab)
i16a[5]=8548
i8a=new Int8Array(ab)
i8a[1]=101
str=String.fromCharCode.apply("", u8a)
buf=new Uint8Array([].map.call(str,function(c){return c.charCodeAt(0)}) )