web前端高级JavaScript - 关于面向对象的一些面试题

135 阅读4分钟
  • 1.下面代码运行的结果
//1. 答案: 0 30
function fun(){
    this.a=0;
    this.b=function(){
        alert(this.a);
    }
}
fun.prototype={
    b:function(){
        this.a=20;
        alert(this.a);
    },
    c:function(){
        this.a=30;
        alert(this.a)
    }
}
var my_fun=new fun();
my_fun.b(); // 0
my_fun.c();// 30
  • 2.写出下面代码执行输出的结果
// 2.答案:'Tomundefinedjoin'
function C1(name) {
    if (name) {
        this.name = name;
    }
}
function C2(name) {
    this.name = name;
}
function C3(name) {
    this.name = name || 'join';
}
C1.prototype.name = 'Tom';
C2.prototype.name = 'Tom';
C3.prototype.name = 'Tom';
alert((new C1().name) + (new C2().name) + (new C3().name));//'Tomundefinedjoin'
//(new C1().name)没有传递参数,所以没有私有name属性,取原型上的公有name属性
//(new C2().name)没有传递参数,默认值为undefined,取私有name属性值为undefined
//(new C3().name)没有传递参数,默认值为undefined,取私有name属性,如果值为undefined则取值join
  • 3.下面代码运行的结果?
//3. 答案:
// 1 undefined 
// ƒ () {this.a = 3;}
// false true true 
// ƒ () {this.a = 2;}
function Fn() {
    let a = 1;
    this.a = a;
}
Fn.prototype.say = function () {
    this.a = 2;
}
Fn.prototype = new Fn;
let f1 = new Fn;

Fn.prototype.b = function () {
    this.a = 3;
};
console.log(f1.a);//1
console.log(f1.prototype);//undefined
console.log(f1.b);//ƒ () {this.a = 3;}
console.log(f1.hasOwnProperty('b'));//false
console.log('b' in f1);//true
console.log(f1.constructor == Fn);//true
console.log(f1.say);//ƒ () {this.a = 2;}
  • 4.写出下面代码执行输出的结果
// 4.答案: 2 4 1 1 2 3 3 3
function Foo() {
    getName = function () {
        console.log(1);
    };
    return this;
}
Foo.getName = function () {
    console.log(2);
};
Foo.prototype.getName = function () {
    console.log(3);
};
var getName = function () {
    console.log(4);
};
function getName() {
    console.log(5);
}
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
(new Foo).getName();//3
new Foo().getName();//3
new new Foo().getName();//3
  • 5.完成如下的需求
//5. 答案:
Number.prototype.plus = function(num){
	num = Number(num);
	if (isNaN(num)) {
		throw new TypeError(`${num}不是一个入有效数字`);
	}
	return	this + num
}
Number.prototype.minus = function(num){
	num = Number(num);
	if (isNaN(num)) {
		throw new TypeError(`${num}不是一个入有效数字`);
	}
	return this - num;
}
let n = 10;
let m = n.plus(10).minus(5);
console.log(m);//=>15(10+10-5)
  • 6.实现如下需求
// 6. 答案:
/*
 * 编写queryURLParams方法实现如下的效果(至少两种方案)
 */
let url="http://www.zhufengpeixun.cn/?lx=1&from=wx#video";
console.log(url.queryURLParams("from")); //=>"wx"
console.log(url.queryURLParams("_HASH")); //=>"video"
//方案一:正则表达式
String.prototype.queryURLParams = function queryURLParams(key){
	let reg = /\?([^&]+)\&(.*)\#(.*)/
	let res = reg.exec(this);
	let obj = {};
	if(res){
		obj[res[1].split('=')[0]] = res[1].split('=')[1]'
		let params = res[2].split('&');
		params.forEach(item=>{
			obj[item.split('=')[0]]=item.split('=')[1]
		});
		obj["_HASH"] = res[3];
		return obj[key];
	}
	return undefined;	
}
//方案二:字符串截取
String.prototype.queryURLParams = function queryURLParams(key){
	let params = url.split('?')[1];
	let hasIndex = params.indexOf('#');
	let hash = params.substr(hashIndex + 1);
	let arrParams = params.substr(0, hashIndex).split('&');
	let obj = {};
	obj["_HASH"] = hash;
	arrParams.forEach(item=>{
		obj[item.split('=')[0]]=item.split('=')[1]
	});
	return obj[key]
}
  • 7.基于ES6中的class重构下面的代码
function Modal(x,y){
    this.x=x;
    this.y=y;
}
Modal.prototype.z=10;
Modal.prototype.getX=function(){
    console.log(this.x);
}
Modal.prototype.getY=function(){
    console.log(this.y);
}
Modal.n=200;
Modal.setNumber=function(n){
    this.n=n;
};
let m = new Model(10,20);

//========答案========
class Modal{
	constructor(x, y){
		this.x = x;
		this.y = y;
	}
	getX(){
		console.log(this.x);
	}
	getY(){
		console.log(this.y);
	}
	static n = 200;
	static setNumber(){
		this.n = n;
	}
}
Modal.prototype.z = 10;
  • 8.代码输出的结果
//8. 答案: {2:1,3:2,length:4,push:f push()}
let obj = {
    2: 3,
    3: 4,
    length: 2,
    push: Array.prototype.push
}
obj.push(1);
obj.push(2);
console.log(obj);
// {2:1,3:2,length:4,push:f push()}
  • 9.a等于什么值会让下面条件成立
//答案:
var a = ?;
if (a == 1 && a == 2 && a == 3) {
    console.log('OK');
}

//方案一:
a = {
	i: 0,
	toString:function(){
		return ++i;
	}
}

//方案二:
a = [1,2,3]
a.toString = a.shift;

//方案三
var i = 0;
Object.defineProperty(window, 'a',{
	get:function(){
		return ++i;
	}
});
  • 10.实现如下需求
let utils = (function(){
    /*
     * toArray:转换为数组的方法
     *   @params
     *      不固定数量,不固定类型
     *   @return
     *      [Array] 返回的处理后的新数组
     * by zhufengpeixun on 2020
     */
    function toArray(){
        //=>实现你的代码(多种办法实现)   
    }

    return {
        toArray
    };
})();
let ary = utils.toArray(10,20,30); //=>[10,20,30]
ary = utils.toArray('A',10,20,30); //=>['A',10,20,30]

//方案一:
function toArray(...params){
	return [...params]
}
//方案二:
function toArray(){
	return [].slice.call(arguments);
}

//方案三:
function toArray(){
	let arr = [];
	for(let i = 0; i < arguments.length; i++){
		arr.push(arguments[i]);
	}
	return arr;
}

  • 11.对象(数组)的深克隆和浅克隆(头条)
//=>浅克隆:只复制对象或者数组的第一级内容
//数组浅克隆
let arr = [];
//方案一
let newArr = arr.slice();
//方案二:
newArr = [...arr]
//普通对象浅克隆
function shallowClone(obj){
	if(typeof obj == null) return null;
	if(typeof obj !== 'object') return obj;
	if(obj instanceof Date) return new Date(obj);
	if(obj instanceof RegExp) return new RegExp(obj);
	let newobj = {};
	for(let key in obj){
		if(obj.hasOwnProperty(key)){
			newObj[key] = obj[key];
		}
	}
	return newObj;
}
//=>深克隆:克隆后数组的每一级都和原始数组没有关联
function deepClone(obj){
	if(typeof obj == null) return null;
	if(typeof obj !== 'object') return obj;
	if(obj instanceof Date) return new Date(obj);
	if(obj instanceof RegExp) return new RegExp(obj);
	let newobj = {};
	for(let key in obj){
		if(obj.hasOwnProperty(key)){
			newObj[key] = deepClone(obj[key]);
		}
	}
	return newObj;
}
//那么请说出,浅克隆都怎么去实现,如何实现深度克隆
let obj = {
    a: 100,
    b: [10, 20, 30],
    c: {
        x: 10
    },
    d: /^\d+$/
};

let arr = [10, [100, 200], {
    x: 10,
    y: 20
}];
  • 12.已知基于 instanceof 可以实现检测:实例是否属于某个类,现在需要自己编写这样的一个方法,实现出 instanceof 的效果
//=>example:要检测的实例
//=>classFunc:要检测的类
function instance_of(example, classFunc) {
	if(example== null) return false;
   	if(typeof example !== 'object') return false;
   	if(typeof classFunc !== 'function') throw new TypeError(`${classFunc}must be a function`);
   	let prototype = Object.getPrototypeOf(example);
   	while(prototype){
   		if (prototype==null) return false;
   		if(prototype === classFunc.prototype)
   		{
   			return true;
   		}
   		prototype = Object.getPrototypeOf(prototype);
   	}
   	return false;
}
let res = instance_of([12,23],Array);
console.log(res); //=>true

附加题(偏难)

  • 1.实现如下需求
//=>编写toType方法,实现数据类型检测
function toType( obj ) {
   //完成你的代码
   	let mapping = {};
	["Number","String","Boolean","Null","Undefined","Symbol","BigInt","Date","RegExp","Function","GeneratorFunction","Array","Object"].forEach(function(item){
		mapping[`[object ${item}]`] = item.toLowerCase();
	});
	let res = Object.prototype.toString.call(obj);
	return mapping[res];
}
console.log(toType(1)); //=>"number"
console.log(toType(NaN)); //=>"number"
console.log(toType([])); //=>"array"
console.log(toType(/^\d+$/)); //=>"regexp"
console.log(toType({})); //=>"object"
  • 2.完成如下需求
~function(){
    function change(){
        //=>实现你的代码
        if(arguments.length === 0) return undefined;
        let obj = arguments[0];
        let params = [].slice.call(arguments, 1);
        obj = this.apply(obj, params);
        obj.name = 'Alibaba';
        return obj;
    };
    
    Function.prototype.change=change;
}();
let obj = {name:'zhufeng'};
function func(x,y){
    this.total=x+y;
    return this;
}
let res = func.change(obj,100,200);
//res => {name:'Alibaba',total:300}
  • 3.完成如下需求
~function(){
    //=>bind方法在IE6~8中不兼容,接下来我们自己基于原生JS实现这个方法
    function bind(obj, ...params){
		let that = this;
		return function(...args){
			params = params.concat(args);
			return that.call(obj, ...params)
		}
    };
    Function.prototype.bind=bind;
}();
var obj = {name:'hello world'};
function func(){
    console.log(this,arguments);
    //=>当点击BODY的时候,执行func方法,输出:obj [100,200,MouseEvent事件对象]
}
document.body.onclick = func.bind(obj,100,200);
  • 4.下面代码的输出结果?为什么?
var name = 'Hello World';
function A(x,y){
    var res=x+y;
    console.log(res,this.name);
}
function B(x,y){
    var res=x-y;
    console.log(res,this.name);
}
B.call(A,40,30);//10 'A'
B.call.call.call(A,20,10);//
Function.prototype.call(A,60,50);
Function.prototype.call.call.call(A,80,70);

在这里插入图片描述