一些简单的js手写代码题 网上很多 自己写来熟悉操作流程的

 

function creatNew () { // 实现 new 方法

let obj = {} // 1.创建一个空对象

let constructor = [].shift.call(arguments)

obj._proto_ = constructor.prototype // 2.链接到原型

let result = constructor.apply(obj, arguments) // 3.绑定this值

return typeof result === 'object' ? result : obj // 4.返回新对象

}

 

class promise { // 实现一个promise函数

constructor (fn) {

this.state = 'pending'

this.value = undefined

this.reson = undefined

var resolve = value => {

if (this.state === 'pending') {

this.state = 'fulfilled'

this.value = value

}

}

var reject = value => {

if (this.state === 'pending') {

this.state = 'rejected'

this.reson = value

}

}

try {

fn(resolve, reject)

} catch (e) {

reject(e)

}

}

 

then (onFulfilled, onRejected) {

switch (this.state) {

case 'fulfilled':

onFulfilled(this.value)

break

case 'rejected':

onRejected(this.value)

break

default:

}

}

},

 

Function.prototype.mycall = function (context) { // 实现一个call函数 本质上是要将this方法挂到目标this上并执行返回

if (typeof this !== 'function') {

throw new TypeError('not function')

}

context = context || window

context.fn = this

var arg = [...arguments].slice(1)

var reslut = context.fn(...arg)

delete context.fn

return reslut

}

 

Function.prototype.myapply = function (context) { // 实现一个apply函数 类似call,但返回的是函数

if (typeof this !== 'function') {

throw new TypeError('not function')

}

context = context || window

context.fn = this // #endregion

let result

if (arguments[1]) {

result = context.fn(...arguments[1])

} else {

result = context.fn()

}

delete context.fn

return result

}

 

Function.prototype.mybind = function (context) { // 实现一个bind函数 类似于call 但是返回的是一个函数

if (typeof this !== 'function') {

throw new TypeError('erro')

}

const _this = this

const arg = [...arguments].slice(1)

return function f () {

if (this instanceof f) {

return new _this(...arg, ...arguments)

} else {

return _this.apply(context, arg.concat(...arguments))

}

}

}

 

let copy1 = { ...{ x: 1 } } // 浅拷贝

let copy2 = Object.assign({}, { x: 1 }) // 浅拷贝

 

const obj = { a: 1, b: { x: 3 } } // 深拷贝

JSON.parse(JSON.stringify(obj)) // 缺点:拷贝对象包含 正则表达式,函数,或者undefined等值会失败

 

function deepClone (obj) { // 递归拷贝

let copy = obj instanceof Arry ? [] : {}

for (const i in obj) {

if (object.hasOwnProlet(i)) {

copy[i] = typeof obj[i] === 'object' ? deepCloen(obj(i)) : obj[i]

}

}

return copy

}

 

function throtte (fn,delay) { // 思路:在规定时间内只触发一次 节流函数

let prev = Date.now()

return function () {

let context = this

let arg = arguments

let now = Date.now()

if (now -prev >= delay) {

fn.apply(context,arg)

prev = Date.now()

}

}

}

function fn () {

console.log(111)

}

addEventListener('scroll', throtte(fn,1000))

 

function debounce (fn,delay) { // 在规定时间内未触发第二次,则执行 防抖函数

let timer = null

return function () {

let context = this

let arg = arguments

clearTimeout(timer)

// 在规定时间内再次触发会先清除定时器后再重设定时器

timer = setTimeout(function(){

fn.apply(context, arg)

},delay)

}

}

function fn () {

console.log('防抖')

}

addEventListener('scroll',debounce(fn,1000))

 

function instanceOf () { // instanceof的原理 右边变量的原型存在于左边变量的原型链上

let leftvalue = left._proto_

let rightvalue = right.prototype

while(true) {

if(leftvalue === null) {

return false

}

if(leftvalue ===rightvalue) {

return true

}

leftvalue = leftvalue._proto_

}

}

 

function creat(obj) { // Object.create 的基本实现原理 将传入的对象作为原型

function F() {}

F.prototype = obj

return new F()

}

 

class EventEmitter { // 实现一个基本的 Event Bus 组件通信,一个触发与监听的过程

constructor () { // 储存事件

this.events = this.events || new Map()

}

addEventListener (type, fn) { // 监听事件

if(!this.events.get(type)){

this.events.set(type,fn)

}

}

emit (type) { // 触发事件

let handle = this.events.get(type)

handle.apply(this, [...arguments].slice(1))

}

}

 

let obj = {} // 实现一个双向数据绑定

let input = document.getElementById('input')

let span = document.getElementById('span')

Object.defineProperty(obj,'text',{

enumerable : true,

configurable : true,

get() {

console.log('获取数据')

},

set() {

console.log('数据更新')

input.value = newVal

span.value = newVal

}

})

input.addEventListener('keyup',function(e) {

obj.text = e.target.value

})

 

class Router { // 实现一个简单路由

constructor() {

this.routes = {} // 路由储存对象

this.currentHash = '' // 当前的hash

this.freshRoute = this.freshRoute.bind(this) // 绑定this 防止后期this被修改指向

window.addEventListener('load',this.freshRoute,false) // 增加监听

window.addEventListener('hashchange',this.freshRoute,false) // 增加监听

}

storeRoute(path,cb) { // 对当前路由进行储存

this.routes[path] = cb || function() {}

}

freshRoute() { // 路由更新

this.currentHash = location.hash.slice(1) || '/'

this.routes[this.currentHash]()

}

}

 

// 手写实现 AJAX

// 1. 简单模式

let xhr = new XMLHttpRequest() // 实例化小黄人

xhr.open(method,url,async) // 初始化通讯连接

xhr.send(data) // 发送请求

xhr.onreadystatechange = () =>{ // 设置状态回调处理请求结果

if(xhr.readyState === 4 && xhr.status === 200) {

console.log(xhr.responseText)

}

}

// 2. 基于promise实现

function ajax(options) {

const url = options.url // 请求地址

const method = options.method.toLocaleLowerCase() || 'get' //请求方式

const async = options.async // 默认设置为异步

const data = options.data // 设置请求参数

const xhr = new XMLHttpRequest() // 实例小黄人

if(options.timeout && options.timeout >0) { // 请求超时

xhr.timeout = options.timeout

}

// 返回一个Promise实例

return new Promise((resolve,reject) =>{

xhr.ontimeout = ()=>reject&&reject('请求超时')

xhr.onreadystatechange = () => { // 监听回调函数

if(xhr.readyState ===4) {

if(xhr.status >=200 && xhr.status<300 || xhr.status===304) { // 200-300 之间表示请求成功,304资源未变,取缓存

resolve && resolve(xhr.responseText)

} else {

reject && reject()

}

}

}

xhr.onerror = err => reject && reject(err) // 错误回调

let paramArr = []

let encodeData

if(data instanceof Object) { // 处理请求参数

for (let key in data) { // 参数拼接需要通过 encodeURIComponent 进行编码

paramArr.push(encodeURIComponent(key) + '=' +encodeURIComponent(data[key]))

}

encodeData = paramArr.join('&')

}

if(method ==='get') { // get请求拼接参数

const index = url.indexOf('?') // 检测url中是否已存在 ? 及其位置

if (index ===1) url+='?'

else if(index!=url.length-1) url+='&'

url += encodeData // 拼接url

}

xhr.open(method,url,async) // 初始化

if(method === 'get') xhr.send(null)

else {

xhr.getResponseHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8') // post 方式需要设置请求头

xhr.send(encodeData)

}

})

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值