[1,2,3].map(parseInt) // 1, NaN, NaN
复制代码
// 实现连续的密集数组
Array.from({length: 100})
Array.apply(null, {length: 100})
[...Array(100)]
(function (){
let i = 0
let a = []
let timer = set Interval(() => {
if (i < 100){
a.push(i)
i++
}else {
clearInterval(timer)
console.log(a)
}
})
})()
(function (){
let i = 0
let a = []
function addItem (){
if (i < 100){
a.push(i)
i++
requestAnimationFrame(addItem)
}else {
console.log(a)
}
}
requestAnimationFrame(addItem)
})()
复制代码
function Foo () {
getName = function () { alert(1) }
return this
}
Foo.getName = function () { alert(2) }
Foo.prototype.getName = function () { alert(3) }
var getName = function () { alert(4) }
function getName () { alert(5) }
//输入的值
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
// 答案 2 4 1 1 2 3 3
复制代码
数组扁平化
function flatDeep(arr){
return Array.isArray(arr) ? arr.reduce((a, b) => [...a, ...flatDeep(b)], [])
}
function flatDeep(arr, origin){
origin = origin || []
return Array.isArray(arr) ? arr.map(item =>{flatDeep(item, origin)}) : origin.push(arr)
}
let a = []
flatDeep([1, [[2], [3, [4]], 5]], a)
复制代码
0.1 + 0.2 != 0.3
// 计算机内部十进制整数转二进制方法:除2取余;十进制小数转二进制方法:乘2除整
0.1 * 2 = 0.2 取整 0
0.2 * 2 = 0.4 取整 0
0.4 * 2 = 0.8 取整 0
0.8 * 2 = 1.6 取整 1
0.6 * 2 = 1.2 取整 1
0.2 * 2 = 0.4 取整 1
。。。
因此0.1 在计算机里理论上应该是无限循环的二进制数,
但是计算机不可能无限大,因此后面的位数会被舍掉
js是遵循IEEE754标准的语言,二进数由64位表示,
一位表示符号位,11位为指数位,后52位表示有效数字,存储小数
复制代码
call和apply方法实现
Function.prototype.call2 = function (context){
context = context || window
context.fn = this
let args = [...arguments].slice(1)
let result = context.fn(...args)
delete context.fn
return result
}
Function.prototype.apply2 = function (context){
context = context || window
context.fn = this
var result
if (arguments[1]){
result = context.fn(...arguments[1])
}else {
result = context.fn()
}
delete context.fn
return result
}
复制代码
bind方法实现
Function.prototype.bind2 = function (context){
let self = this
context = context || window
let args = [].slice.call(arguments, 1)
var fBound = function (){
let bind Args = [].slice.call(arguments)
return self.apply(this instanceof fBound ? this : context, args.concat(bind Args))
}
fBound.prototype = Object.create(self.prototype)
return fBound
}
复制代码
new方法实现
function _new (){
let context = {}
let args = [].slice.call(arguments)
let con = args.shift()
context = Object.create(con.prototype)
let ret = con.apply(context, args)
return (typeof ret == 'object' && ret != null) ? ret : context
}
复制代码
js创建对象的方式
// 工厂模式
function createObj(name){
let obj = {}
obj.name = name
obj.say = function (){
return obj.name
}
}
// 构造函数模式
function Person(name){
this.name = name
this.say = function (){
return this.name
}
}
var person = new Person('Mike' )
// 原型模式
function Person (){}
Person.prototype.name = 'Mike'
Person.prototype.say = function (){
return this.name
}
// 构造函数和原型组合模式
function Person(name){
this.name = name
}
Person.prototype.say = function (){
return this.name
}
var person = new Person('Mike' )
// 动态原型模式
function Person(name){
this.name = name
if (typeof this.say !== 'function' ){
Person.prototype.say = function (){
return this.name
}
}
}
// 寄生构造函数模式
function Person(name){
let obj = {}
obj.name = name
obj.say = function (){
return this.name
}
return obj
}
// 稳妥构造函数模式
function Person(name){
let obj = {}
obj.say = function (){
return name
}
return obj
}
复制代码
js继承
// 原型继承
function Parent (){
this.name = 'Mike'
}
function Child (){}
Child.prototype = new Parent()
Child.prototype.constructor = Child
console.log(new Child().name) // Mike
// 构造函数继承
function Parent(name){
this.name = name
}
function Child(name){
Parent.call(this, name)
}
// 原型和构造函数组合模式
function Parent(name){
this.name = name
}
Parent.prototype.say = function (){
return this.name
}
function Child(name){
Parent.call(this, name)
}
Child.prototype = new Parent()
Child.prototype.constructor = Child
console.log(new Child('Mike' ).say())
// 原型式继承
function createObj(proto){
function F (){}
F.prototype = proto
return new F()
// 等价于
return Object.create(proto)
}
// 寄生组合继承
function Parent(name){
this.name = name
}
Parent.prototype.say = function (){
return this.name
}
function Child(name){
Parent.call(this, name)
this.age = 8
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
let child = new Child('Mike' )
console.log(child instanceof Child) // true
console.log(child instanceof Parent) // true
复制代码
js原型与原型链
原型与原型链
js类型判断
基本类型判断 typeof 但是typeof null === 'object' typeof (function a (){}) === 'function'
实例判断 instanceof new Person() instanceof Person
内置对象 toString 可以判断的类型有
var number = 1; // [object Number]
var string = '123' ; // [object String]
var boolean = true ; // [object Boolean]
var und = undefined; // [object Undefined]
var nul = null; // [object Null]
var obj = {a: 1} // [object Object]
var array = [1, 2, 3]; // [object Array]
var date = new Date(); // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g; // [object RegExp]
var func = function a (){}; // [object Function]
Object.prototype.toString.call(Math); // [object Math]
Object.prototype.toString.call(JSON); // [object JSON]
Object.prototype.toString.call(arguments); // [object Arguments]
// 判断是否为plainObject--由Object创建的对象,或者原型为null的对象
function plainObject(obj){
let class2type = {}
hasOwn = class2type.hasOwnProperty
if (typeof obj != 'object' || !obj) return false
let proto = Object.getPropertyOf(obj)
if (!proto){
return true
}
let ctor = proto.constructor
// 对于函数的toString方法判断,要找Function.property上的toString方法
return typeof ctor === 'function' && hasOwn.toString.call(ctor) === hasOwn.toString.call(Object)
}
复制代码
js深浅拷贝
function shallow(src){
if (typeof src === 'object' ){
let target = src instanceof Array ? [] : {}
for (let key in src){
if (src.hasOwnProperty(key){
target[key] = src[key]
}
}
return target
}
return
}
function deep(src){
if (typeof src === 'object' ){
let target = src instanceof Array ? [] : {}
for (let key in src){
if (src.hasOwnProperty(key)){
target[key] = typeof src[key] == 'object' ? deep(src[key]) : src[key]
}
}
return target
}
return
}
function deepObject(src){
let copy = Object.create(Object.getPropertyOf(src)
copyProperties(src, copy)
return copy
function copyProperties(src, copy){
Object.getOwnPropertyNames(src).forEach(propKey => {
Object.defineProperty(copy, propKey, Object.getPropertyDescriptor(src, propKey))
})
}
}
function deepObjectEs7(src){
return Object.create(Object.getPropertyOf(src), Object.getOwnPropertyDescriptors(src))
}
复制代码
防抖
// 多用于鼠标事件,滚动事件,表示当事件停止一定时间后响应
function debounce(func, wait ){
var timer
return function (){
let args = arguments
let context = this
clearTimeout(timer)
timer = set Timeout(() => {
func.apply(context, args)
}, wait )
}
}
function debounce(func, wait , immediate){
var timer
return function (){
let args = arguments
let context = this
if (timer) clearTimeout(timer)
if (immediate){
let callNow = !timer
timer = set Timeout(() => {
timer = null
})
if (callNow){
func.apply(context, this)
}
}else {
timer = set Timeout(() => {
func.apply(context, this)
}, wait )
}
}
}
复制代码
节流
// 多用于文本输入,表示在用户连续输入期间,一定时间间隔后响应,定期发生
// 时间戳实现方式 满足立即执行一次
function throttle(func, wait ){
let prev = 0
return function (){
let context = this
let args = arguments
let now = + new Date()
if (now - prev > wait ){
func.apply(context, args)
prev = now
}
}
}
// 定时器实现方式 满足离开后还会执行一次
function throttle(func, wait ){
let timer
return function (){
let context = this
let args = arguments
if (!timer) {
timer = set Timeout(() => {
func.apply(context, args)
timer = null
},wait )
}
}
}
// 第三版
function throttle(func, wait ){
let timer
let prev = 0
let context
function later (){
timer = null
func.apply(context, args)
prev = + new Date()
}
return function (){
context = this
let args = arguments
let now = + new Date()
let remain = wait - (now - prev)
if (remain < 0 || remain > wait ){
if (timer){
clearTimeout(timer)
timer = null
}
func.apply(context, args)
}else if (!timer){
timer = set Timeout(later, remain)
}
}
}
// leading: 是否立即执行
// tailing: 最后一次是否执行
function throttle4(func, wait , options) {
let prev = 0
let timer
let result
if (!options) {
options = {}
}
return function () {
let context = this
let args = arguments
let now = + new Date()
if (!prev && !options.leading) {
pre = now
}
let remaining = wait - (now - prev)
if (remaining < 0 || remaining > wait ) {
if (timer) {
clearTimeout(timer)
timer = null
prev = now
}
result = func.apply(context, args)
} else if (!timer && options.tailing) {
this.timer = set Timeout(() => {
func.apply(context, args)
timer = null
prev = options.leading == false ? 0 : new Date()
}, remaining)
}
return result
}
}
复制代码