前端开发面试题之 JavaScript(一)

知识点
数据类型、运算、对象、function、继承、闭包、作用域、原型链、事件、RegExp、JSON、Ajax、DOM、BOM、内存泄漏、跨域、异步加载、模板引擎、前端MVC、前端MVVM、路由、模块化、Canvas、jQuery、ECMAScript 2015(ES6)、Node.js、AngularJS、React、CommonJS、AMD、CMD …
题目&答案

介绍一下 JS 的基本数据类型。

Undefined、Null、Boolean、Number、String

介绍一下 JS 有哪些内置对象。

Object 是 JavaScript 中所有对象的父对象
数据封装类对象:Object、Array、Boolean、Number、String
其他对象:Function、Argument、Math、Date、RegExp、Error

列举几条 JavaScript 的基本代码规范。

(1)不要在同一行声明多个变量
(2)如果你不知道数组的长度,使用 push
(3)请使用 ===/!== 来比较 true/false 或者数值
(4)对字符串使用单引号 ''(因为大多时候我们的字符串。特别html会出现")
(5)使用对象字面量替代 new Array 这种形式
(6)绝对不要在一个非函数块里声明一个函数,把那个函数赋给一个变量。浏览器允许你这么做,但是它们解析不同
(7)不要使用全局函数
(8)总是使用 var 来声明变量,如果不这么做将导致产生全局变量,我们要避免污染全局命名空间
(9)Switch 语句必须带有 default 分支
(10)使用 /**...*/ 进行多行注释,包括描述,指定类型以及参数值和返回值
(11)函数不应该有时候有返回值,有时候没有返回值
(12)语句结束一定要加分号
(13)for 循环必须使用大括号
(14)if 语句必须使用大括号
(15)for-in 循环中的变量应该使用 var 关键字明确限定作用域,从而避免作用域污染
(16)避免单个字符名,让你的变量名有描述意义
(17)当命名对象、函数和实例时使用驼峰命名规则
(18)给对象原型分配方法,而不是用一个新的对象覆盖原型,覆盖原型会使继承出现问题
(19)当给事件附加数据时,传入一个哈希而不是原始值,这可以让后面的贡献者加入更多数据到事件数据里,而不用找出并更新那个事件的事件处理器

介绍一下 JavaScript 原型,原型链,它们有何特点?

每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,
于是就这样一直找下去,也就是我们平时所说的原型链的概念。
关系:instance.constructor.prototype = instance.__proto__
//
特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本,当我们修改原型时,与之相关的对象也会继承这一改变。
//
当我们需要一个属性时,JavaScript引擎会先看当前对象中是否有这个属性,如果没有的话,就会查找它的prototype对象是否有这个属性,如此递推下去,一致检索到Object内建对象。
function Func(){}
Func.prototype.name = "Xiaosong";
Func.prototype.getInfo = function() {
    return this.name;
}
var person = new Func();
console.log(person.getInfo());
//"Xiaosong"
console.log(Func.prototype);
//Func { name = "Xiaosong", getInfo = function() }

JavaScript 有几种类型的值?能否画一下它们的内存图?

栈:原始数据类型(Undefined,Null,Boolean,Number,String)
堆:引用数据类型(对象、数组、函数)
两种类型的区别:存储位置不同
//
原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

JavaScript 如何实现继承?

(1)构造继承
(2)原型继承
(3)实例继承
(4)拷贝继承
//
原型prototype机制或apply和call方法去实现较简单,建议使用构造函数与原型混合方式。
function Parent() {
    this.name = 'song';
}
function Child() {
    this.age = 28;
}
Child.prototype = new Parent(); //通过原型,继承了Parent
//
var demo = new Child()l;
alert(demo.age);
alert(demo.name); //得到被继承的属性

JavaScript 有哪几种创建对象的方式?

javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON;但写法有很多种,也能混合使用。
//
(1)对象字面量的方式
person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"};
(2)用function来模拟无参的构造函数
function Person(){}
var person = new Person(); //定义一个function,如果使用new"实例化",该function可以看作是一个Class
person.name = "Xiaosong";
person.age = "23";
person.work = function() {
    alert("Hello " + person.name);
}
person.work();
(3)用function来模拟参构造函数来实现(用this关键字定义构造的上下文属性)
function Person(name,age,hobby) {
    this.name = name; //this作用域:当前对象
    this.age = age;
    this.work = work;
    this.info = function() {
        alert("我叫" + this.name + ",今年" + this.age + "岁,是个" + this.work);
    }
}
var Xiaosong = new Person("WooKong",23,"程序猿"); //实例化、创建对象
Xiaosong.info(); //调用info()方法
(4)用工厂方式来创建(内置对象)
var jsCreater = new Object();
jsCreater.name = "Brendan Eich"; //JavaScript的发明者
jsCreater.work = "JavaScript";
jsCreater.info = function() {
    alert("我是"+this.work+"的发明者"+this.name);
}
jsCreater.info();
(5)用原型方式来创建
function Standard(){}
Standard.prototype.name = "ECMAScript";
Standard.prototype.event = function() {
    alert(this.name+"是脚本语言标准规范");
}
var jiaoben = new Standard();
jiaoben.event();
(6)用混合方式来创建
function iPhone(name,event) {
    this.name = name;
    this.event = event;
}
iPhone.prototype.sell = function() {
    alert("我是"+this.name+",我是iPhone5s的"+this.event+"~ haha!");
}
var SE = new iPhone("iPhone SE","官方翻新机");
SE.sell();

eval 是做什么的?

它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,因为不安全,非常耗性能(2次,一次解析成js语句,一次执行)。

什么是 document 对象?什么是 window 对象?
null 和 undefined 有何区别?

null        表示一个对象被定义了,值为“空值”;
undefined   表示不存在这个值。
//
typeof undefined
    //"undefined"
    undefined :是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但是还没有定义。当尝试读取时会返回 undefined; 
    例如变量被声明了,但没有赋值时,就等于undefined。
//
typeof null
    //"object"
    null : 是一个对象(空对象, 没有任何属性和方法);
    例如作为函数的参数,表示该函数的参数不是对象;
//
注意:
    在验证null时,一定要使用 === ,因为 == 无法分别 null 和 undefined

能否写一个通用的事件侦听器函数?

//Event工具集,from:github.com/markyun
markyun.Event = {
    //页面加载完成后
    readyEvent: function(fn) {
        if (fn == null) {
            fn = document;
        }
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = fn;
        }else{
            window.onload = function() {
                oldonload();
                fn();
            };
        }
    },
    //视能力分别使用 demo0 || demo1 || IE 方式来绑定事件
    //参数:操作的元素,事件名称,事件处理程序
    addEvent: function(element,type,handler) {
        if (element.addEventListener) {
            //事件类型、需要执行的函数、是否捕捉
            element.addEventListener(type,handler,false);
        }else if (element.attachEvent) {
            element.attachEvent('on' + type, function() {
                handler.call(element);
            });
        }else {
            element['on' + type] = handler;
        }
    },
    //移除事件
    removeEvent: function(element,type,handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type,handler,false);
        }else if (element.datachEvent) {
            element.datachEvent('on' + type,handler);
        }else{
            element['on' + type] = null;
        }
    },
    //阻止事件(主要是事件冒泡,因为IE不支持事件捕获)
    stopPropagation: function(ev) {
        if (ev.stopPropagation) {
            ev.stopPropagation();
        }else {
            ev.cancelBubble = true;
        }
    },
    //取消事件的默认行为
    preventDefault: function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        }else{
            event.returnValue = false;
        }
    },
    //获取事件目标
    getTarget: function(event) {
        return event.target || event.srcElemnt;
    },
    //获取event对象的引用,取到事件的所有信息,确保随时能使用event;
    getEvent: function(e) {
        var ev = e || window.event;
        if (!ev) {
            var c = this.getEvent.caller;
            while(c) {
                ev = c.argument[0];
                if (ev && Event == ev.constructor) {
                    break;
                }
                c = c.caller;
            }
        }
        retrun ev;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_23350817/article/details/87879436
今日推荐