JavaScript基础面试题及答案①
- 1 介绍JavaScript的基本数据类型
- 3 jQurry使用建议
- 4 Ajax使用
- 5 JavaScript有几种类型的值?
- 6 栈和堆的区别?
- 7 JavaScript实现继承的几种方式
- 8 JavaScript创建对象的几种方法:
- 9JavaScript作用域
- 9 JavaScript作用域链
- 10 闭包
- 11 谈谈你对this的理解
- 12 什么是window对象,什么是document对象?
- 13 null和undefined的区别
- 14 什么事件流?IE与网景的事件机制有何区别?如何阻止冒泡
- 15 e.target和this的区别
- 16 如何判断一个对象是否属于某个类?
- 17 DOM操作
- 18 对call()和apply()的理解
- 19 如何删除一个Cookie?
- 20 渐进增强和优雅降级
1 介绍JavaScript的基本数据类型
Number、String、Boolean、Null、Undefined
Object是JavaScript中所有对象的父元素
数据封装类对象:Object、Array、Boolean、Number和String
其他对象:Function、Arguments、Array、Math、Date、RegExp、Error
新类型:Symbol
##2 说说书写JavaScript的基本规范
1)不要在同一行声明多个变量
2)使用 === 或 !== 来比较true/false或者数值
3)switch必须带有default分支
4)函数应该有返回值
5)for if else 必须使用大括号
6)语句结束打分号
3 jQurry使用建议
1、尽量减少对Dom元素的访问和操作
2、尽量减少给dom元素绑定多个相同类型的事件处理函数,可以将多个想同类型事件处理函数合并到一个处理函数,通过数据状态来处理分支
3、尽量避免使用toggle事件
4 Ajax使用
全称:Asynchornous JavaScript And XML
所谓异步,就是局部向服务器发送请求,全局不用等待,而是可以同时做其他的事情,等到有了结果他会自己根据设定进行后续操作,与此同时,页面不会发生整体刷新,局部刷新,提高了用户的整体体验
创建Ajax的过程:
1)创建XMLHttpRequest对象(异步调用对象)
var xhr = new XMLHttpRequest()||new ActiveXobject("Microsoft.XMLHTTP");
- 建立连接(方法、URL、是否异步)
xhr.open("get","请求路径",true);
3)发送请求
xhr.send(date)
- 接收返回值
xhr.onreadyStatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
//获取数据
var txt = xhr.responseText;
console.log(txt)
}else{
console.log("error")
}
5 JavaScript有几种类型的值?
基本数据类型 存储在栈中
复合数据类型(对象) 存储在堆中
6 栈和堆的区别?
栈(stack):由编译器自动分配释放,存放函数的参数值,局部变量等;
堆(heap):一般由程序员分配释放,若程序袁不释放,程序结束是可能有操作系统数释放
7 JavaScript实现继承的几种方式
- 构造函数继承
//构造函数的核心思想是
//通过call()或apply()方法在子构造函数的内部调用父构造函数,从而获取到父对象中的属性和方法
function Person(name){
this.legs = 2;
this.mouse = 1;
this.name = name;
this.walk = function(){
console.log(this.name+"有"+this.legs+"条腿");
}
}
//中国人
function Chinese(name){
Person.call(this,name);
}
//实例化对象
var Chinese = new Chinese("zs");
//调用对象方法
Chinese.walk();
}
2)组合继承
<script>
/*
组合继承:因为原型链继承只能继承原型对象中的属性和方法,
而构造函数又只能继承实例对象中的属性和方法,便有了组合继承
组合继承也叫伪经典继承,其核心是:
1、将原型链继承和构造函数继承组合在一起
原型链实现对原型对象属性何方法的继承
构造函数实现对实例对象的属性和方法的继承
*/
function Person(name){
this.legs = 2;
this.mouse = 1;
this.name = name ;
this.walk = function(){
console.log(this.name+"有"+this.legs+"条腿");
}
}
Person.prototype.say = function() {
console.log("我的名字叫"+this.name);
}
//中国人
function Chinese(name){
Person.call(this,name);
}
Chinese.prototype = new Person();
Chinese.prototype.constructor = Chinese;
//实例化对象
var chinese = new Chinese("张三")
//调用对象方法
chinese.walk();
chinese.say();
</script>
3)利用空对象作为中介继承
<script>
function Boss(){}
Boss.prototype.money = 9999999;
function fa(n,a){
this.name = n;
this.age = a;
}
//创建一个空的构造函数 通过空对象进行传值
function Nul(){}
Nul.prototype = Boss.prototype;
//让fa的原型对象指向创建的空的构造函数
fa.prototype = new Nul();
//让fa的构造函数指向fa
fa.prototype.constructor = fa;
// 创建fa的实例对象
var son = new fa("tom",16);
console.log(son.name,son.age,son.money);
//通过fa改变原型对象 但是Boss原型对象的值不能被修稿
fa.prototype.money = 100;
console.log(fa.prototype);
var boss_ = new Boss();
console.log(boss_.money);//999999
</script>
8 JavaScript创建对象的几种方法:
1) 工厂方法
function creatPerson(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayName = function() {
window.alert(this.name);
};
return obj;
}
2)构造函数方法
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
window.alert(this.name);
};
}
3)原型方法
function Person() {
}
Person.prototype = {
constructor : Person,
name : "Ning",
age : "23",
sayName : function() {
window.alert(this.name);
}
};
这种方法有些缺陷,类里属性的值都是在原型里给定的
4)组合使用构造函数和原型方法(推荐)
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
constructor : Person,
sayName : function() {
window.alert(this.name);
}
};
将构造函数方法和原型函数方法结合使用是最常用的定义类的方法。这种方法的好处就是实现了属性定义和方法定义的分离。比如我们创建了两个对象person1和person2,它们分别传入各自的name值和age值,但sayName()方法可以同时使用原型里定义的。
9JavaScript作用域
1)变量作用域
1、变量作用域就是变量的可访问范围
2、变量作用域可以减少变量的命名冲突,提高程序的可靠性
3、变量作用域可以分为全局作用域和局部作用域
全局作用域:
1.全局作用域中的变量全局可以使用(函数内外都可以访问)
2.在函数外部定义的变量成为全局变量
3.在函数内部没有使用var声明的变量直接赋值的变量也为全局变量
4.全局变量只有在浏览器关闭时才会注销,比较占用资源
var num1 = 10;
function fun1(){
console.log(num1);
}
fun1();
console.log(num1)
局部作用域:
1.局部作用域中的变量只能在作用域内部使用(函数内部使用)
2.在函数内部通过var定义的变量为局部变量
3.函数的形参实际上也是局部变量
4.局部变量在函数执行结束后会销毁,比较节省内存空间
function fun1(){
var num = 20;
console.log(num);
}
fun1();
console.log(num)
9 JavaScript作用域链
1)只要是代码,就至少有一个作用域
2)函数内部为局部作用域
3)内部函数可以访问外部函数的变量
4)但外部函数无法访问内部函数的变量
5)内部函数访问的外部函数中的变量,采取的是链式查找的方式来决定取哪个值,这种方式成为作用域链(就近原则)
作用域链的原理和原型链很类似,如果这个变量在自己的作用域中没有,那么他会寻找父级的,直到最顶层。
注意:JS没有块级作用域,若要形成块级作用域可以通过(function(){{}})立即执行的形式实现。
10 闭包
1)闭包(closure)指能够读取到其他函数内部变量的函数
2)闭包的实现:在函数内部在定义一个函数,把内部函数作为返回值
3)闭包的优点:避免全局变量污染
4)闭包的缺点:容易造成内存泄漏
function a(){
var num = 20;
return function(){
console.log(num);
}
}
var b = a();
b();
3)闭包的作用
1、延伸变量作用范围,可以在函数外部访问到内部局部变量
2、可以让局部变量在函数执行结束后不释放,保存在内存中
function a(){
var num = 20;
return function(){
console.log(num++);
}
}
var b = a();
b();
b();
4)闭包的缺点:
1、闭包会使得函数中的变量都被保存在网页中,内存消耗很大,所以不能滥用闭包,可能导致内存泄漏
2、闭包会在函数外部,改变函数内部变量的值
11 谈谈你对this的理解
1)this总是指向函数的直接调用者(而非间接调用者)
2)如果有new关键字,this指向new出来的那个对象
3)在事件中this指向目标元素,特殊的是IE的attachEvent中的this总是指向全局对象window。
12 什么是window对象,什么是document对象?
1)window对象代表浏览器中打开的一个窗口。
2)document对象代表整个html文档。
实际上document对象是window对象的一个属性。
13 null和undefined的区别
1)null表示一个对象被定义了,但存放了空指针,转换为数值时值为0。
typeof(null) – object;
2)undefined表示声明的变量为初始化,转换为数值是为NAN。
typeof(undefined) – undefined;
14 什么事件流?IE与网景的事件机制有何区别?如何阻止冒泡
1)事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
DOM事件流分为三个阶段:捕获阶段 、当前目标阶段 、冒泡阶段
2)捕获阶段:IE最早提出,事件逐级向下传播
冒泡阶段:网景最早提出,事件逐级向上传播
3)阻止冒泡:jQuery中使用event.stopPropagation() 方法;旧IE的方法ev.cancelBubble = true;
reutrn false也能阻止默认行为没有兼容性问题(return false 只针对传统注册方式有效)
15 e.target和this的区别
1)this是事件绑定的元素(绑定这个事件处理函数的元素)
2)e.target是事件触发的元素
**通常情况下target和this是一致的
**但有一种情况不同,那就是在事件冒泡时(父子元素有相同事件,单击子元素,父元素的事件处理函数也会被触发执行)
**这是this指向的是父元素,因为它是绑定事件的元素对象
**而target指向的是子元素,因为他是触发事件的那个具体元素对象
***比如给ul绑定了click事件,当点击里面的li时,this表示ul而e.target表示li
16 如何判断一个对象是否属于某个类?
使用instanceof 即if(a instanceof Person){alert(‘yes’);}
17 DOM操作
1)创建节点对象:
**creatDocumentFragment() // 创建一个DOM片段
**creatElement() // 创建一个具体的元素
**creatTextNode() // 创建一个文本节点
2)添加、移除、替换、插入
**appendChild()
**removeChild()
**repliceChild()
**insertBefore() // 在已有的子节点前插入一个新的子节点
3)查找
**getElementsByTagName() // 通过标签名称
**getElementsByName() // 通过元素的name属性值
**getElementById() // 通过元素id,具有唯一性
18 对call()和apply()的理解
call() 方法和apply() 方法的作用相同,动态改变某个类的某个方法的运行换寂静。他们的区别在于接收参数的方式不同。在使用call()方法时,传递给函数的的参数必须逐个列举出来。使用apply()时,传递给函数的是参数数组。
19 如何删除一个Cookie?
1)将Cookie的失效时间设置为过去的时间(expires)
document.cookie = "user = " + encodeURIComponent("name") + ';
expires = ' + new Date(0);
2)将系统时间设置为当前时间往前一点
var date = nwe Date();
date.setDate(date.getDate()-1);
20 渐进增强和优雅降级
渐进增强:针对浏览器低版本进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进,达到更好的用户体验。
优雅降级:一开始就构造完整的功能,然后在针对低版本浏览器进行兼容
感谢支持:@快乐养兔