面试之笔试篇(JS内置原型方法)
程序员文章站
2022-06-09 13:02:48
...
1. 实现一个new
先看一个真实的new
var Dog = function (name){
this.name = name
}
Dog.prototype.getName = function(){
return this.name
}
var dog = new Dog('miao')
console.log(dog.getName()) // 'miao'
实现一个_new函数
function _new(fn, ...args){
var obj = Object.create(fn.prototype)
var ret = fn.apply(obj, args)
return (ret instanceof Object ? ret : obj)
}
//如果构造函数有返回值,并且是对象,还有可能是return new xx() 类似这样的
var Foo = function(){
return {
name: 'xx'
}
}
var dog = _new(Dog, 'wang')
console.log(dog.getName()) // 'wang'
var xx = _new(Foo)
console.log(xx.name) // 'xx'
2. 手写Promise
可参考之前写的一篇手写Promise,主要还是要弄懂链式调用的实现机制。
3. 实现一个call或apply
Function.prototype.call1 = function(context = window, ...args){
context.fn = this;
const result = context.fn(...args)
delete context.fn;
return result;
}
Function.prototype.apply1 = function(context, args){
context = context || window; //修复this指定为null时的情况
context.fn = this;
const result = context.fn(...args)
delete context.fn;
return result;
}
测试代码
//测试call和apply
var obj = {
name: 'xxx',
getName: function(str){
return this.name + str
}
}
var name = '我是全局变量'
console.log(obj.getName.call1(obj, '哈哈'))
console.log(obj.getName.call1(undefined, '哈哈'))
console.log(obj.getName.apply1(null, ['哈哈']))
4. 实现一个bind
// 实现一个bind
Function.prototype.bind1= function(context, ...args){
if(typeof this != "function") {
throw Error("not a function")
}
const fn = this;
const resFn = function(argsRs){
// 这里考虑使用new调用的情况 new的优先级高于显示绑定
return fn.apply((this instanceof resFn) ? this : context,args.concat(...argsRs))
}
// 考虑原型链的问题,使用了寄生式组合继承
// function create(proto){
// function tmp(){}
// tmp.prototype = proto;
// return new tmp()
// }
// resFn.prototype = create(this.prototype);
resFn.prototype = Object.create(this.prototype);
return resFn
}
// 测试
var obj1 = {
name: 'xx1'
}
const foo = obj.getName.bind1(obj1, 'haa')
foo('111') //xx1haa
5. JSON.parse()
// 实现一个JSON.parse()
var parse = function(str){
return (new Function('return '+ str))()
}
6. 实现一个JSON.stringify
/**
* 思路:
* 1.对 number、null、boolean、string基础类型数据原样返回,“undefined|函数” 返回 undefined
* 2. 引用类型,删除值为“undefined|函数” 的对象属性,将值为 “undefined|函数” 的数组元素输出为null
* 3. 关于深层嵌套的对象,递归即可
*/
// 值是 undefined|函数
function isUnDefOrFun(type) {
return /undefined|function/.test(type);
}
function isString(val){
return typeof val === 'string'
}
function stringify(obj) {
const type = typeof obj
// obj不是对象
if ( type !== "object") {
// “undefined|函数” 返回 undefined ,其他的直接加 "" 返回
if(isUnDefOrFun(type)){
return undefined
}else {
return `"${obj}"`
}
} else {
// 分数组和对象两种
let str = '';
const isArray = Array.isArray(obj)
for(let k in obj){
let val = obj[k]
const t = typeof val
// 这里要对null 进行排除
if(t === "object" && val !== null){
str += `,"${k}":${stringify(val)}`
}else{
if(isString(val)) val = `"${val}"`;
if(isArray){
if(isUnDefOrFun(t)){
val = null
}
str += `,${val}`
}else{
if(!isUnDefOrFun(t)){
str += `,"${k}":${val}`;
}
}
}
}
str = str.substring(1)
return (isArray ? `"[${str}]"`: `"{${str}}"`)
}
}
7. 实现一个继承
// 实现一个继承
function Parent(name){
this.name = name
}
Parent.prototype.getName = function(){
return this.name
}
function Child(name, parentName){
Parent.call(this, parentName)
this.name = name
}
function create(obj){
function F(){}
F.prototype = obj;
return new F()
}
Child.prototype = create(Parent.prototype)
Child.prototype.constructor = Child
// Child.prototype = Object.create(Parent.prototype)
var child = new Child('小明', '美呀')
console.log(child.name)
console.log(child.getName())
8. 实现Object.creat
//实现一个Object.create()
function create(obj){
function F(){}
F.prototype = obj
return new F()
}
9. 实现一个instansOf
// 实现一个instanceOf
// 右边的原型在左边的原型链上可以找到
function instanceOf(left, right){
let proto = left.__proto__
const prototype = right.prototype
while(true){
if(proto === null) return false
if(proto === prototype) return true
proto = proto.__proto__
}
}
var a = {
name: 'xxx'
}
console.log(instanceOf(a,Object))
10. 实现一个flat
[[1,2],[3]].flat() => [1,2,3]
Array.prototype.flat1 = function() {
//递归
let arr = this // 拿到实例
let ret = []
for (let item of arr) {
if (Array.isArray(item)) {
ret.push(...item.flat1())
} else {
ret.push(item)
}
}
return ret
}
持续更新中…
如果你正在面试,希望能帮到你,如果你有更牛逼的方法,也欢迎一起交流~~~
微信:yuan_zi_xxx
上一篇: 自定义标签中获取dao
下一篇: PHP Global定义全局变量使用说明
推荐阅读