Xi-Yuer

Xi-Yuer

github

Javascript

JavaScript#

Collection of JS Syntax#

Implementing call function#

Function.prototype.wxcall = function (thisArg, ...arg) {
  var fn = this;
  thisArg = thisArg ? Object(thisArg) : window;
  thisArg.fn = fn;
  return thisArg.fn(...arg);
};

console.log(foo.wxcall('abc', 10, 20));
console.log(foo.wxcall({}, 10, 20));
let result = foo.wxcall(null, 10, 20);
console.log(result);

Implementing apply function#

Function.prototype.wxapply = function (thisArg, arrArg) {
  var fn = this;
  thisArg = thisArg ? Object(thisArg) : window;
  thisArg.fn = fn;
  arrArg ? thisArg.fn(...arrArg) : thisArg.fn(); // Check if parameters are passed
  delete thisArg.fn;
};

function foo(a, b, c) {
  console.log(a + b + c);
}
foo.wxapply({}, [10, 20, 30]);
foo.wxapply({}, [10, 20, 30]);

Implementing slice function#

Array.prototype.wxslice = function (start, end) {
  var arr = this;
  let newArr = [];
  for (let i = start; i < end; i++) {
    newArr.push(arr[i]);
  }
  return newArr;
};
console.log([1, 2, 3, 4, 5, 6, 7, 8].wxslice(0, 2));

defineProperty#

const obj = {
  name: 'Tom',
  age: 18,
};

// Object.defineProperty(obj,'name',{
//     get:function(){
//         console.log('Detected access to name property');
//     },
//     set:function(){
//         console.log('Detected setting of name property');
//     }
// })

// console.log(obj.name); //Detected access to name property
// obj.name = 'Kobe' //Detected setting of name property

// Can get all keys of the object
Object.keys(obj).forEach(key => {
  let value = obj[key];
  console.log(key);
  /*  name
        age
     */
  Object.defineProperty(obj, key, {
    get: function () {
      console.log('Detected access to property');
      return value;
    },
    set: function (newValue) {
      console.log('Detected setting of name property');
    },
  });
});
console.log(obj.name); //Detected access to name property
obj.name = 'Kobe'; //Detected setting of name property

Proxy#

const obj = {
  name: 'Tom',
  age: 18,
  height: 1.88,
};

// Create a proxy

// Parameter one: proxy the obj object Parameter two: handler (there are 13 types of handlers)
const objProxy = new Proxy(obj, {
  // Getter handler (automatically called when getting value)
  get: function (target, key) {
    // target is the proxied object; key
    console.log(target); //{ name: 'Tom', age: 18, height: 1.88 }
    console.log(key); // name, the key being accessed
    return target[key];
  },

  // Setter handler (automatically called when setting value)
  set: function (target, key, newValue) {
    target[key] = newValue;
  },
});
// Access
// console.log(objProxy); // { name: 'Tom', age: 18, height: 1.88 }
// console.log(objProxy.name); // Tom
// console.log(objProxy.age); // 18
// Set
// objProxy.name = "Kobe"; // through proxy
console.log(objProxy.name); // Kobe

Reactive Principle#

class Depend {
  constructor() {
    this.reactiveFns = [];
  }
  // Collect dependencies
  addDepend(reactiveFn) {
    this.reactiveFns.push(reactiveFn);
  }
  // Execute dependencies
  notify() {
    // Iterate through all dependencies and execute
    this.reactiveFns.forEach(fn => {
      fn();
    });
  }
}

const depend = new Depend();
const obj = {
  name: 'Tom',
  age: 18,
};
// Listen for changes in properties (proxy, object.defineProperty) and execute depend.notify()
const objProxy = new Proxy(obj, {
  get: function (target, key, receiver) {
    // Return the value
    return Reflect.get(target, key, receiver);
  },
  // Automatically executes this method when setting value to the proxy object
  set: function (target, key, newvalue, receiver) {
    Reflect.set(target, key, newvalue, receiver);
    // Notify depend to execute dependencies when setting value
    depend.notify();
  },
});
function foo() {
  console.log('Executing code');
}
depend.addDepend(foo); // Collect dependencies
objProxy.name = 'Lilei';

Iterator#

// An iterator must meet the following conditions
// 1. It is an object
// 2. The object has a next method
// 3. The method returns an object with done and value properties
// const iterator = {
//   next: function () {
//     return { done: true, value: "" };
//   },
// };

// Array
const arr = ['abc', 'cba', 'nba'];
// Use an iterator to traverse the array
// Create an iterator object to access the array
let index = 0;
const arrIterator = {
  next: function () {
    if (index < arr.length) {
      return { done: false, value: arr[index++] };
    } else {
      return { done: true, value: undefined };
    }
  },
};
console.log(index); //0
console.log(arrIterator.next()); //{ done: false, value: 'abc' }

console.log(index); //1
console.log(arrIterator.next()); //{ done: false, value: 'cba' }

console.log(index); //2
console.log(arrIterator.next()); //{ done: false, value: 'nba' }

console.log(index); //3
console.log(arrIterator.next()); //{ done: true, value: undefined }

console.log(index); //3

// Iterator optimization

Iterator Generator Function#

function createArryIterator(arr) {
  let index = 0;
  return {
    next: function () {
      if (index < arr.length) {
        return { done: false, value: arr[index++] };
      } else {
        return { done: true, value: undefined };
      }
    },
  };
}

const names = ['Tom', 'Sily', 'Lusy'];
const nameIterator = createArryIterator(names);
console.log(nameIterator.next()); //{ done: false, value: 'Tom' }
console.log(nameIterator.next()); //{ done: false, value: 'Sily' }
console.log(nameIterator.next()); //{ done: false, value: 'Lusy' }

const nums = [1, 2, 3, 4, 5];
const numsIterator = createArryIterator(nums);
console.log(numsIterator.next()); //{ done: false, value: 1 }
console.log(numsIterator.next()); //{ done: false, value: 2 }
console.log(numsIterator.next()); //{ done: false, value: 3 }
console.log(numsIterator.next()); //{ done: false, value: 4 }

// Create an infinite iterator
function createNumberIterator() {
  let index = 0;
  return {
    next: function () {
      return {
        done: false,
        value: index++,
      };
    },
  };
}
const numberInterator = createNumberIterator();
console.log(numberInterator.next()); //{ done: false, value: 0 }
console.log(numberInterator.next()); //{ done: false, value: 1 }
console.log(numberInterator.next()); //{ done: false, value: 2 }
console.log(numberInterator.next()); //{ done: false, value: 3 }
console.log(numberInterator.next()); //{ done: false, value: 4 }
console.log(numberInterator.next()); //{ done: false, value: 5 } ......

Iterable Object#

// This object returns an iterator
const iterabalObj = {
  names: ['Tom', 'Sily', 'Lusy'],
  // An iterable object needs to have the [Symbol.iterator] property, which corresponds to a function that returns an iterator
  [Symbol.iterator]: function () {
    let index = 0;
    return {
      next: () => {
        if (index < this.names.length) {
          return { done: false, value: this.names[index++] };
        } else {
          return { done: true, value: undefined };
        }
      },
    };
  },
};
console.log(iterabalObj[Symbol.iterator]); //[Function: [Symbol.iterator]]

// Calling this function will generate a new iterator for us
const iterator = iterabalObj[Symbol.iterator]();
console.log(iterator.next()); //{ done: false, value: 'Tom' }
console.log(iterator.next()); //{ done: false, value: 'Sily' }
console.log(iterator.next()); //{ done: false, value: 'Lusy' }

// New iterator
const iterator1 = iterabalObj[Symbol.iterator]();
console.log(iterator1.next()); //{ done: false, value: 'Tom' }
console.log(iterator1.next()); //{ done: false, value: 'Sily' }
console.log(iterator1.next()); //{ done: false, value: 'Lusy' }

for (const item of iterabalObj) {
  console.log(item);
  //   Tom
  //   Sily
  //   Lusy
}

Generator#

// Generator function (*)
function* foo() {
  console.log(1);
  yield;

  console.log(2);
  // yield can control the function to pause
  yield;

  console.log(3);
  yield;

  console.log(4);
}
// Calling the generator function does not execute it directly, but returns a generator object
// console.log(foo()); // Object [Generator] {}
const Generator = foo();

// Start executing the first segment of code (code before yield) by executing next()
Generator.next(); //1

// Start executing the second segment of code
Generator.next(); //2

// Start executing the third segment of code
Generator.next(); //3

// Start executing the fourth segment of code
Generator.next(); //4

Generator Function Execution Flow#

function* foo() {
  console.log(1);
  yield 'Return value'; // The return value of this segment of code
  console.log(2);
  yield;
  console.log(3);
  yield;
  console.log(4);
}
const Generator = foo();
// The return value is value, done: false
console.log(Generator.next()); // { value: { name: 'tom', age: 18 }, done: false }
// Generator.next() // 1

// Generator function function*
// yield keyword can pause the code here
// Executing the generator function returns a generator object
// Calling the next method of this generator object will execute the code before yield in order,
// Calling next() again will continue executing the code before the next yield
// If you want to return some values before each yield, you can write the return value after yield

Generator Parameter Issue#

// Parameter issue for each segment of code
function* foo() {
  console.log(1);
  // The parameter passed to the next function during the second execution will be assigned to the return value of the first yield
  const n = yield;

  // The second segment of code is executed during the second next execution
  console.log(2 * n); // 20
  yield 'Return value: console.log(Generator.next()) // Return value ......';

  console.log(3);
  yield;

  console.log(4);
}

const Generator = foo();
Generator.next();
Generator.next(10);

// Execute Generator.next() twice
// During the second execution, a parameter is passed
// This parameter will be used as the return value of the first yield, const n = yield uses n to accept this return value

Macro Tasks & Micro Tasks#

// Code after await belongs to micro tasks
// async function a() {
//     console.log('a')
//     await b()
//     console.log('a end')
// }

// async function b() {
//     console.log('b')
// }

// a()

// setTimeout(function () {
//     console.log('setTimeout')
// }, 0)

// new Promise(function (resolve, reject) {
//     console.log('promise')
//     resolve()
// }).then(function () {
//     console.log('then')
// })

// console.log('main end')

// //
setTimeout(function () {
  console.log('8');
}, 0);
async function async1() {
  console.log('1');
  const data = await async2();
  console.log('6');
  return data;
}
async function async2() {
  return new Promise(resolve => {
    console.log('2');
    resolve('Result of async2');
  }).then(data => {
    console.log('4');
    return data;
  });
}
async1().then(data => {
  console.log('7');
  console.log(data);
});
new Promise(function (resolve) {
  console.log('3');
  resolve();
}).then(function () {
  console.log('5');
});

//

console.log('script start');

async function async1() {
  await async2();
  console.log('async1 end');
}
async function async2() {
  console.log('async2 end');
}
async1();

setTimeout(function () {
  console.log('setTimeout');
}, 0);

new Promise(resolve => {
  console.log('Promise');
  resolve();
})
  .then(function () {
    console.log('promise1');
  })
  .then(function () {
    console.log('promise2');
  });

console.log('script end');

//

// console.log('script start')

// async function async1() {
//     await async2()
//     console.log('async1 end')
// }
// async function async2() {
//     console.log('async2 end')
//     return Promise.resolve().then(()=>{
//         console.log('async2 end1')
//     })
// }
// async1()

// setTimeout(function() {
//     console.log('setTimeout')
// }, 0)

// new Promise(resolve => {
//     console.log('Promise')
//     resolve()
// })
// .then(function() {
//     console.log('promise1')
// })
// .then(function() {
//     console.log('promise2')
// })

// console.log('script end')

// async function async1(){
//   await async2()
//   console.log('async1 end')
// }
// async function async2(){}
// async1();
// new Promise(function(resolve){
//   resolve();
// }).then(function(){
//   console.log('promise2')
// }).then(function() {
//   console.log('promise3')
// }).then(function() {
//   console.log('promise4')
// })

Debounce#

function debounce(fn, delay) {
  let timer = null;
  return (...args) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}

// Whether to execute directly for the first time
function debounce(fn, delay, isImmediately = true) {
  let timer = null;
  let Immediately = isImmediately;
  return (...args) => {
    if (timer) clearTimeout(timer);
    Immediately
      ? fn.apply(this, args)
      : (timer = setTimeout(() => fn.apply(this, args), delay));
    Immediately = !isImmediately;
  };
}

Throttle#

function throttle(fn, delay) {
  let pre = 0;
  return (...args) => {
    let now = new Date();
    if (now - pre > delay) {
      fn.apply(this, args);
    }
    pre = now;
  };
}

Deep Clone#

function isObject(value) {
  const valueType = typeof value;
  return (value !== null && valueType === 'object') || valueType === 'function';
}

function deepClone(originValue) {
  // Check if it is a symbol type, create a new symbol
  if (typeof originValue === 'symbol') {
    return Symbol(originValue.description);
  }
  if (typeof originValue === 'function') {
    // If it is a function, return it directly
    return originValue;
  }
  if (originValue instanceof Set) {
    return new Set([...originValue]);
  }
  if (originValue instanceof Map) {
    return new Map([...originValue]);
  }
  // Check if the passed origin is an object type
  if (!isObject(originValue)) {
    return originValue;
  }
  // Check if the passed object is an array or an object
  const newObject = Array.isArray(originValue) ? [] : {};
  // Iterate through the original object and clone the property values to the new object
  for (const key in originValue) {
    newObject[key] = deepClone(originValue[key]); // Recursive call
  }
  const symbolKeys = Object.getOwnPropertySymbols(originValue);
  for (const skey of symbolKeys) {
    newObject[skey] = deepClone(originValue[skey]);
  }
  return newObject;
}
const obj1 = {
  name: 'Tom',
  friends: {
    one: {
      name: 'sily',
    },
    two: {
      name: 'kobe',
    },
  },
};
console.log(deepClone(obj1));

Event Bus#

class EventBus {
  constructor() {
    this.eventBus = {};
  }

  on(eventName, eventCallBack, thisArg) {
    let handlers = this.eventBus[eventName];
    if (!handlers) {
      handlers = [];
      this.eventBus[eventName] = handlers;
    }
    handlers.push({
      eventCallBack,
      thisArg,
    });
  }
  off() {}
  emit(eventName, ...payload) {
    const handlers = this.eventBus[eventName];
    if (!handlers) return;
    handlers.forEach(handler => {
      handler.eventCallBack.apply(handler.thisArg, payload);
    });
  }
}
const eventBus = new EventBus();

// main.js
eventBus.on(
  'a',
  function (payload) {
    console.log(payload);
  },
  this
);
// util.js
eventBus.emit('a', { name: 'Tom' });

Implementing slice function#

Array.prototype.wxslice = function (start, end) {
    var arr = this;
    let newArr = [];
    for (let i = start; i < end; i++) {
        newArr.push(arr[i]);
    }
    return newArr;
}
console.log([1, 2, 3, 4, 5, 6, 7, 8].wxslice(0, 2));

Implementing call function#

// Add a wxapply method to all functions
Function.prototype.wxcall = function (thisArg, ...arg) { // Pass in this and parameters
    // Here we need to execute the function that calls this method
    // Question: Which function executed call
    var fn = this; // Who called it is this
    // Convert thisArg to object type to prevent passing in a number or other non-object type
    // If null or undefined is passed, bind this to window
    thisArg = thisArg ? Object(thisArg) : window;
    thisArg.fn = fn; // Execute this function
    thisArg.fn(...arg); // Bind this and parameters
    delete thisArg.fn;
}

function foo(a, b) {
    console.log('Executing');
    console.log(this);
    console.log(a + b);
}
foo.wxcall({}, 10, 20);

Function.prototype.wxcall = function (thisArg, ...arg) {
var fn = this;
thisArg = thisArg ? Object(thisArg) : window;
thisArg.fn = fn;
return thisArg.fn(...arg);
}

function foo(a, b) {
return a + b;
}
console.log(foo.wxcall('abc', 10, 20));
console.log(foo.wxcall({}, 10, 20));
let result = foo.wxcall(null, 10, 20);
console.log(result);


## Function to create an iterator

```js
function createArryIterator(arr) {
    let index = 0;
    return {
        next: function () {
            if (index < arr.length) {
                return { done: false, value: arr[index++] };
            } else {
                return { done: true, value: undefined };
            }
        }
    };
}

const names = ['Tom', 'Sily', 'Lusy'];
const nameIterator = createArryIterator(names);
console.log(nameIterator.next()); //{ done: false, value: 'Tom' }
console.log(nameIterator.next()); //{ done: false, value: 'Sily' }
console.log(nameIterator.next()); //{ done: false, value: 'Lusy' }

const nums = [1, 2, 3, 4, 5];
const numsIterator = createArryIterator(nums);
console.log(numsIterator.next()); //{ done: false, value: 1 }
console.log(numsIterator.next()); //{ done: false, value: 2 }
console.log(numsIterator.next()); //{ done: false, value: 3 }
console.log(numsIterator.next()); //{ done: false, value: 4 }

// Create an infinite iterator
function createNumberIterator() {
    let index = 0;
    return {
        next: function () {
            return {
                done: false,
                value: index++
            };
        }
    };
}
const numberInterator = createNumberIterator();
console.log(numberInterator.next()); //{ done: false, value: 0 }
console.log(numberInterator.next()); //{ done: false, value: 1 }
console.log(numberInterator.next()); //{ done: false, value: 2 }
console.log(numberInterator.next()); //{ done: false, value: 3 }
console.log(numberInterator.next()); //{ done: false, value: 4 }
console.log(numberInterator.next()); //{ done: false, value: 5 } ......

Implementing apply function#

Function.prototype.wxapply = function (thisArg, arrArg) {
    var fn = this;
    thisArg = thisArg ? Object(thisArg) : window;
    thisArg.fn = fn;
    arrArg ? thisArg.fn(...arrArg) : thisArg.fn(); // Check if parameters are passed
    delete thisArg.fn;
}

function foo(a, b, c) {
    console.log(a + b + c);
}
foo.wxapply({}, [10, 20, 30]);
foo.wxapply({}, [10, 20, 30]);

Implementing instanceof#

function isPrototypeOf(obj) {
    var proto = this.prototype;
    while (obj) {
        if (obj === proto) {
            return true;
        }
        obj = Object.getPrototypeOf(obj);
    }
    return false;
}

Iterable Object#

// This object returns an iterator
const iterabalObj = {
    names: ['Tom', 'Sily', 'Lusy'],
    // An iterable object needs to have the [Symbol.iterator] property, which corresponds to a function that returns an iterator
    [Symbol.iterator]: function () {
        let index = 0;
        return {
            next: () => {
                if (index < this.names.length) {
                    return { done: false, value: this.names[index++] };
                } else {
                    return { done: true, value: undefined };
                }
            }
        };
    }
}
console.log(iterabalObj[Symbol.iterator]); //[Function: [Symbol.iterator]]

// Calling this function will generate a new iterator for us
const iterator = iterabalObj[Symbol.iterator]();
console.log(iterator.next()); //{ done: false, value: 'Tom' }
console.log(iterator.next()); //{ done: false, value: 'Sily' }
console.log(iterator.next()); //{ done: false, value: 'Lusy' }

// New iterator
const iterator1 = iterabalObj[Symbol.iterator]();
console.log(iterator1.next()); //{ done: false, value: 'Tom' }
console.log(iterator1.next()); //{ done: false, value: 'Sily' }
console.log(iterator1.next()); //{ done: false, value: 'Lusy' }

for (const item of iterabalObj) {
    console.log(item);
    //   Tom
    //   Sily
    //   Lusy
}

Listening to Object Operations#

const obj = {
    name: 'Tom',
    age: 18
}

// Object.defineProperty(obj,'name',{
//     get:function(){
//         console.log('Detected access to name property');
//     },
//     set:function(){
//         console.log('Detected setting of name property');
//     }
// })

// console.log(obj.name); //Detected access to name property
// obj.name = 'Kobe' //Detected setting of name property

// Can get all keys of the object
Object.keys(obj).forEach(key => {
    let value = obj[key];
    console.log(key);
    /*  name
        age
     */
    Object.defineProperty(obj, key, {
        get: function () {
            console.log('Detected access to property');
            return value;
        },
        set: function (newValue) {
            console.log('Detected setting of name property');
        }
    });
});
console.log(obj.name); //Detected access to name property
obj.name = 'Kobe'; //Detected setting of name property

Reactive Principle#

class Depend {
    constructor() {
        this.reactiveFns = [];
    }
    // Collect dependencies
    addDepend(reactiveFn) {
        this.reactiveFns.push(reactiveFn);
    }
    // Execute dependencies
    notify() {
        // Iterate through all dependencies and execute
        this.reactiveFns.forEach(fn => {
            fn();
        });
    }
}

const depend = new Depend();
const obj = {
    name: 'Tom',
    age: 18,
};
// Listen for changes in properties (proxy, object.defineProperty) and execute depend.notify()
const objProxy = new Proxy(obj, {
    get: function (target, key, receiver) {
        // Return the value
        return Reflect.get(target, key, receiver);
    },
    // Automatically executes this method when setting value to the proxy object
    set: function (target, key, newvalue, receiver) {
        Reflect.set(target, key, newvalue, receiver);
        // Notify depend to execute dependencies when setting value
        depend.notify();
    }
});
function foo() {
    console.log('Executing code');
}
depend.addDepend(foo); // Collect dependencies
objProxy.name = 'Lilei';

Iterator#

// An iterator must meet the following conditions
// 1. It is an object
// 2. The object has a next method
// 3. The method returns an object with done and value properties
// const iterator = {
//   next: function () {
//     return { done: true, value: "" };
//   },
// };

// Array
const arr = ['abc', 'cba', 'nba'];
// Use an iterator to traverse the array
// Create an iterator object to access the array
let index = 0;
const arrIterator = {
    next: function () {
        if (index < arr.length) {
            return { done: false, value: arr[index++] };
        } else {
            return { done: true, value: undefined };
        }
    }
};
console.log(index); //0
console.log(arrIterator.next()); //{ done: false, value: 'abc' }

console.log(index); //1
console.log(arrIterator.next()); //{ done: false, value: 'cba' }

console.log(index); //2
console.log(arrIterator.next()); //{ done: false, value: 'nba' }

console.log(index); //3
console.log(arrIterator.next()); //{ done: true, value: undefined }

console.log(index); //3  

// Iterator optimization

Custom Class Iterability#

// Custom iterable class
class Classroom {
  constructor(address, name, students) {
    this.address = address;
    this.name = name;
    this.students = students;
  }
  entry(newStudents) {
    this.students.push(newStudents);
  }
  [Symbol.iterator]() {
    // This function returns an iterator
    let index = 0;
    return {
      next: () => {
        if (index < this.students.length) {
          return { done: false, value: this.students[index++] };
        } else {
          return { done: true, value: undefined };
        }
      },
    };
  }
}

const classroom = new Classroom("Beijing", "Primary School", ["tom", "sily", "kobe"]);
for (item of classroom) {
    console.log(item);
            // tom
            // sily
            // kobe
}

Built-in Iterable Object Creation#

const names = ['abc', 'cba', 'nba'];
console.log(names[Symbol.iterator]); //[Function: values]

const iterator = names[Symbol.iterator]() // Executing this function returns an iterator

console.log(iterator.next()); //{ value: 'abc', done: false }
console.log(iterator.next()); //{ value: 'cba', done: false }  
console.log(iterator.next()); //{ value: 'nba', done: false }    
console.log(iterator.next()); //{ value: undefined, done: true }    

Generator Parameter Issue#

// Parameter issue for each segment of code
function* foo() {
    console.log(1);
    // The parameter passed to the next function during the second execution will be assigned to the return value of the first yield
    const n = yield;

    // The second segment of code is executed during the second next execution
    console.log(2 * n);     // 20
    yield 'Return value :console.log(Generator.next()) // Return value ......';

    console.log(3);
    yield;

    console.log(4);
}

const Generator = foo();
Generator.next();
Generator.next(10); 

Generator Function Execution Flow#

function* foo() {
    console.log(1);
    yield 'Return value'; // The return value of this segment of code
    console.log(2);
    yield;
    console.log(3);
    yield;
    console.log(4);
}
const Generator = foo();
// The return value is value, done: false
console.log(Generator.next()); // { value: { name: 'tom', age: 18 }, done: false }
// Generator.next() // 1

Proxy Usage#

const obj = {
  name: "Tom",
  age: 18,
  height: 1.88,
};

// Create a proxy

// Parameter one: proxy the obj object Parameter two: handler (there are 13 types of handlers)
const objProxy = new Proxy(obj, {
    // Getter handler (automatically called when getting value)
    get: function(target, key) {
        console.log(target);
        console.log(key);
        return target[key];
    },
    // Setter handler (automatically called when setting value)
    set: function(target, key, newValue) {
        target[key] = newValue;
    },
    // Listen for in handler
    has: function(target, key) {
        console.log('Using in operator');
        return key in target;
    },    
    // Listen for delete handler
    deleteProperty: function(target, key) {
        console.log('Detected property deletion');
        delete target[key];
    }
}); 
// console.log(objProxy.name); // Kobe
// console.log('name' in objProxy); // true

delete objProxy.name;

Prototype#

function Fn() {}

Fn.prototype = {
    name: 'Tom',
    age: 18
}
const p1 = new Fn();
const p2 = new Fn();

console.log(p1.name);
console.log(p2.name);
console.log(p2.toString());

Array Deduplication#

const unique = (arr) => {
    if (!Array.isArray(arr)) {
        return console.error('Parameter must be an array');
    }

    const temArr = [];

    for (let i = 0; i < arr.length; i++) {
        if (temArr.indexOf(arr[i]) === -1) {
            temArr.push(arr[i]);
        }
        // OR
        // if (temArr.includes(arr[i])) {
        //     temArr.push(arr[i]);
        // }
    }
    return temArr.sort();
}

const result = unique([1, 1, 1, 2, 3, 2, 3, 4, 5, 6, 4, 2, 9, 8, 7, 8, 7, 6]);

console.log(result);

console.log(typeof 3..toString());
// 3 ===> 0000 0011  ===> 0000 1100
console.log(3 << 2);
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.