前端常见笔试题

题目1

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();
复制代码
  1. Foo.getName(); //2 获取Foo对象的getName属性,原型和实例上属性相同,优先从实例上查找
  2. getName(); //4 由于直接调用getName 1,2,3 排除 此处有变量声明提早函数声明提早 两个坑 下面举例说明
// 代码以下
    console.log(x);
    var x = 1;
    function x (){};
    // 实际执行结果
    var x;
    function x() {};
    console.log(x);
    x = 1;
复制代码
  1. Foo().getName(); //1 先执行Foo()返回的this指向window,此时的getName()就至关于window.getName(),因为该函数第一行getName = function () { alert (1); };没有用var声明,因此是操做的是全局变量,所以修改了先前的getName()函数
  2. getName(); //1同上window.getName()
  3. new Foo.getName(); //2 考察js运算符优先级 这里的new操做符是无参数的因此优先级低 实际执行结果new ((Foo.getName)())
  4. new Foo().getName(); //3 实际至关于(new Foo()).getName()

执行构造函数,分为三种状况 1.没有返回值,返回实例化对象 2.如有返回值检查其返回值是否为引用类型。若是是非引用类型,如基本类型(string、number、boolean、null、undefind)则与无返回值相同,返回实例化对象。``3.若返回值是引用类型,则实际返回值为这个引用类型 返回this this不能做为引用类型, 返回实例化对象javascript

  1. new new Foo().getName(); //3先初始化Foo的实例化对象,将其原型上的getName做为构造函数再次new,仍是3.
    )

题目2 将data中的数据按照age 从小到大排序

var data = [
        { name: 'Jay', age: 10 },
        { name: 'Jerry', age: 15 },
        { name: 'Merry', age: 12 },
        { name: 'Tom', age: 14 },
        { name: 'Richard', age: 22 }
    ];
    function compare(prop) {
        return function (obj1, obj2) {
            var value1 = obj1[prop];
            var value2 = obj2[prop];
            return value1 - value2;
        }
    }
    data.sort(compare('age'));
    // 极简写法
    data.sort((a,b)=>(a.age-b.age))
复制代码

题目3 数组扁平化

var data = [1, 2, [3, 4, 5, [6, 7, 8]], 9, 10];
    function flatten(arr) {
        let result = []
        for (let i = 0; i < arr.length; i++) {
            if (Array.isArray(arr[i])) {
                result = result.concat(arguments.callee(arr[i]))
            } else {
                result.push(arr[i])
            }
        }
        return result
    }
    // 极简写法
    function flatten(arr) {
        return arr.reduce((init, next) => {
            return init.concat(Array.isArray(next) ? flatten(next) : next)
        }), []
    }
复制代码

4.简述call,apply,bind区别

call跟apply的用法几乎同样,惟一的不一样就是传递的参数不一样,call只能一个参数一个参数的传入。apply则只支持传入一个数组,哪怕是一个参数也要是数组形式。最终调用函数时候这个数组会拆成一个个参数分别传入。至于bind方法,他是直接改变这个函数的this指向而且返回一个新的函数,以后再次调用这个函数的时候this都是指向bind绑定的第一个参数。bind传餐方式跟call方法一致。java

举个例子

// 有只猫叫小黑,小黑会吃鱼
const cat = {
    name: '小黑',
    eatFish(...args) {
        console.log('this指向=>', this);
        console.log('...args', args);
        console.log(this.name + '吃鱼');
    },
}
// 有只狗叫大毛,大毛会吃骨头
const dog = {
    name: '大毛',
    eatBone(...args) {
        console.log('this指向=>', this);
        console.log('...args', args);
        console.log(this.name + '吃骨头');
    },
}

console.log('=================== call =========================');
// 有一天大毛想吃鱼了,但是它不知道怎么吃。怎么办?小黑说我吃的时候喂你吃
cat.eatFish.call(dog, '汪汪汪', 'call')
// 大毛为了表示感谢,决定下次吃骨头的时候也喂小黑吃
dog.eatBone.call(cat, '喵喵喵', 'call')

console.log('=================== apply =========================');
cat.eatFish.apply(dog, ['汪汪汪', 'apply'])
dog.eatBone.apply(cat, ['喵喵喵', 'apply'])

console.log('=================== bind =========================');
// 有一天他们以为每次吃的时候再喂太麻烦了。干脆直接教对方怎么吃
const eatFishSkill = cat.eatFish.bind(dog, '汪汪汪', 'bind')
const eatBoneSkill = dog.eatBone.bind(cat, '喵喵喵', 'bind')
eatFishSkill()
eatBoneSkill()
复制代码

call语法 fun.call(thisArg, arg1, arg2, ...)

  • thisArg: 在fun函数运行时指定的this值。须要注意的是,指定的this值并不必定是该函数执行时真正的this值,若是这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
  • arg1, arg2, ...: 指定的参数列表

apply语法 fun.apply(thisArg, [argsArray])

  • thisArg在 fun 函数运行时指定的 this 值。须要注意的是,指定的 this 值并不必定是该函数执行时真正的 this 值,若是这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
  • argsArray一个数组或者类数组对象,其中的数组元素将做为单独的参数传给 fun 函数。若是该参数的值为null 或 undefined,则表示不须要传入任何参数。从ECMAScript 5 开始可使用类数组对象。

bind语法 fun.bind(thisArg[, arg1[, arg2[, ...]]])

  • thisArg 当绑定函数被调用时,该参数会做为原函数运行时的 this 指向。当使用new 操做符调用绑定函数时,该参数无效。
  • arg1, arg2, ... 当绑定函数被调用时,这些参数将置于实参以前传递给被绑定的方法。

相关文章
相关标签/搜索