JS 之基础
1、 介绍JavaScript的基本数据类型
Number、String 、Boolean 、Null、Undefined
Object 是 JavaScript 中所有对象的父对象
数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error
新类型:Symbol
2、 说说写JavaScript的基本规范?
(1) 不要在同一行声明多个变量
(2) 使用 ===或 !==来比较true/false或者数值
(3) switch必须带有default分支
(4) 函数应该有返回值
(5) for if else 必须使用大括号
(6) 语句结束加分号
(7) 命名要有意义,使用驼峰命名法
3、 jQuery使用建议
(1) 尽量减少对dom元素的访问和操作
(2) 尽量避免给dom元素绑定多个相同类型的事件处理函数,可以将多个相同类型事件
处理函数合并到一个处理函数,通过数据状态来处理分支
(3) 尽量避免使用toggle事件
4、 Ajax使用
全称 :Asynchronous Javascript And XML
所谓异步,就是向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会发生整页刷新的,提高了用户体验。
创建Ajax的过程:
- 创建XMLHttpRequest对象(异步调用对象)
var xhr = new XMLHttpRequest();
- 创建新的Http请求(方法、URL、是否异步)
xhr.open(‘get’,’example.php’,false);
- 设置响应HTTP请求状态变化的函数。
onreadystatechange事件中readyState属性等于4。响应的HTTP状态为200(OK)或者304(Not Modified)。 - 发送http请求
xhr.send(data);
- 获取异步调用返回的数据
注意:
(1) 页面初次加载时,尽量在web服务器一次性输出所有相关的数据,只在页面加载完成之后,用户进行操作时采用ajax进行交互。
(2) 同步ajax在IE上会产生页面假死的问题。所以建议采用异步ajax。
(3) 尽量减少ajax请求次数
(4) ajax安全问题,对于敏感数据在服务器端处理,避免在客户端处理过滤。对于关键业务逻辑代码也必须放在服务器端处理
5、 JavaScript有几种类型的值?你能画一下他们的内存图吗?
基本数据类型存储在栈中,引用数据类型(对象)存储在堆中,指针放在栈中。
两种类型的区别是:存储位置不同;原始数据类型直接存储在栈中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;引用数据类型存储在堆中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能
引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
6、 栈和堆的区别?
栈(stack):由编译器自动分配释放,存放函数的参数值,局部变量等;
堆(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统释放。
7、 Javascript实现继承的几种方式
JavaScript实现继承的3种方法
1)、借用构造函数法(又叫经典继承)
function SuperType(name) {
this.name = name;
this.sayName = function() {
window.alert(this.name);
};
}
function SubType(name, age) {
SuperType.call(this, name); //在这里借用了父类的构造函数
this.age = age;
}
2)、对象冒充
function SuperType(name) {
this.name = name;
this.sayName = function() {
window.alert(this.name);
};
}
function SubType(name, age) {
this.supertype = SuperType; //在这里使用了对象冒充
this.supertype(name);
this.age = age;
}
3)、组合继承(最常用)
function SuperType(name) {
this.name = name;
}
SuperType.prototype = {
sayName : function() {
window.alert(this.name);
}
};
function SubType(name, age) {
SuperType.call(this, name); //在这里继承属性
this.age = age;
}
SubType.prototype = new SuperType(); //这里继承方法
8 、Javascript创建对象的几种方式?
JavaScript定义类的4种方法
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()方法可以同时使用原型里定义的。
9、Javascript作用链域
作用域链的原理和原型链很类似,如果这个变量在自己的作用域中没有,那么它会寻找父级的,直到最顶层。
注意:JS没有块级作用域,若要形成块级作用域,可通过(function(){})();立即执行的形式实现。
10、 谈谈this的理解
- this总是指向函数的直接调用者(而非间接调用者)
- 如果有new关键字,this指向new出来的那个对象
- 在事件中,this指向目标元素,特殊的是IE的attachEvent中的this总是指向全局对象window。
11、 eval是做什么的
它的功能是把对应的字符串解析成JS代码并运行;应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
12、 什么是window对象? 什么是document对象?
window对象代表浏览器中打开的一个窗口。document对象代表整个html文档。实际上,document对象是window对象的一个属性
13、 null,undefined的区别?
null表示一个对象被定义了,但存放了空指针,转换为数值时为0。
undefined表示声明的变量未初始化,转换为数值时为NAN。
typeof(null) – object;
typeof(undefined) – undefined
14、关于事件,IE与火狐的事件机制有什么区别?如何阻止冒泡?
IE为事件冒泡,Firefox同时支持事件捕获和事件冒泡。但并非所有浏览器都支持事件捕获。jQuery中使用event.stopPropagation()方法可阻止冒泡;(旧IE的方法 ev.cancelBubble = true;)
15、 什么是闭包(closure),为什么要用它?
闭包指的是一个函数可以访问另一个函数作用域中变量。常见的构造方法,是在一个函数内部定义另外一个函数。内部函数可以引用外层的变量;外层变量不会被垃圾回收机制回收。
注意,闭包的原理是作用域链,所以闭包访问的上级作用域中的变量是个对象,其值为其运算结束后的最后一个值。
优点:避免全局变量污染。缺点:容易造成内存泄漏。
例子:
function makeFunc() {
var name = "Mozilla";
function displayName() {
console.log(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc(); //输出Mozilla
myFunc 变成一个 闭包。闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。在我们的例子中,myFunc 是一个闭包,由 displayName 函数和闭包创建时存在的 “Mozilla” 字符串形成。
16、javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么?
除了正常模式运行外,ECMAscript添加了第二种运行模式:“严格模式”。
作用:
- 消除js不合理,不严谨地方,减少怪异行为
- 消除代码运行的不安全之处,
- 提高编译器的效率,增加运行速度
- 为未来的js新版本做铺垫。
17、 如何判断一个对象是否属于某个类?
使用instanceof 即if(a instanceof Person){alert(‘yes’);}
18、 new操作符具体干了什么呢?
- 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
- 属性和方法被加入到 this 引用的对象中。
- 新创建的对象由 this 所引用,并且最后隐式的返回 this 。
19、 Javascript中,执行时对象查找时,永远不会去查找原型的函数?
Object.hasOwnProperty(proName):是用来判断一个对象是否有你给出名称的属性。不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。
20、 对JSON的了解?
全称:JavaScript Object Notation
JSON中对象通过“{}”来标识,一个“{}”代表一个对象,如{“AreaId”:”123”},对象的值是键值对的形式(key:value)。JSON是JS的一个严格的子集,一种轻量级的数据交换格式,类似于xml。数据格式简单,易于读写,占用带宽小。
两个函数:
JSON.parse(str)
解析JSON字符串 把JSON字符串变成JavaScript值或对象
JSON.stringify(obj)
将一个JavaScript值(对象或者数组)转换为一个 JSON字符串
eval(’(‘+json+’)’)
用eval方法注意加括号 而且这种方式更容易被攻击
21、JS延迟加载的方式有哪些?
JS的延迟加载有助与提高页面的加载速度。
defer和async、动态创建DOM方式(用得最多)、按需异步载入JS
defer:延迟脚本。立即下载,但延迟执行(延迟到整个页面都解析完毕后再运行),按照脚本出现的先后顺序执行。
async:异步脚本。下载完立即执行,但不保证按照脚本出现的先后顺序执行。
22、 同步和异步的区别?
同步的概念在操作系统中:不同进程协同完成某项工作而先后次序调整(通过阻塞、唤醒等方式),同步强调的是顺序性,谁先谁后。异步不存在顺序性。
同步:浏览器访问服务器,用户看到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容之后进行下一步操作。
异步:浏览器访问服务器请求,用户正常操作,浏览器在后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。
23、什么是跨域问题 ,如何解决跨域问题?
什么是跨域?
要明白什么是跨域之前,首先要明白什么是同源策略?
同源策略就是用来限制从一个源加载的文档或脚本与来自另一个源的资源进行交互。那怎样判断是否是同源呢?
如果协议,端口(如果指定了)和主机对于两个页面是相同的,则两个页面具有相同的源,也就是同源。也就是说,要同时满足以下3个条件,才能叫同源:
协议相同
端口相同
主机相同
举个例子就一目了然了:
我们来看下面的页面是否与 http://store.company.com/dir/index.html 是同源的?
http://store.company.com/dir/index2.html 同源
http://store.company.com/dir2/index3.html 同源 虽然在不同文件夹下
https://store.company.com/secure.html 不同源 不同的协议(https)
http://store.company.com:81/dir/index.html 不同源 不同的端口(81)
http://news.company.com/dir/other.html 不同源 不同的主机(news)
跨域的几种解决方案
1)、document.domain方法
我们来看一个具体场景:有一个页面 http://www.example.com/a.html ,它里面有一个iframe,这个iframe的源是 http://example.com/b.html ,很显然它们是不同源的,所以我们无法在父页面中操控子页面的内容。
解决方案如下:
<!-- b.html -->
<script>
document.domain = 'example.com';
</script>
<!-- a.html -->
<script>
document.domain = 'example.com';
var iframe = document.getElementById('iframe').contentWindow.document;
//后面就可以操作iframe里的内容了...
</script>
所以我们只要将两个页面的document.domain设置成一致就可以了,要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域。
但是,这种方法只能解决主域相同的跨域问题。
2)、window.name方法
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
我们来看一个具体场景,在一个页面 example.com/a.html 中,我们想获取 data.com/data.html 中的数据,以下是解决方案:
<!-- data.html -->
<script>
window.name = 'data'; //这是就是我们需要通信的数据
</script>
<!-- a.html -->
<html>
<head>
<script>
function getData () {
var iframe = document.getElementById('iframe');
iframe.src = 'example.com/b.html'; // 这里让iframe与父页面同源
iframe.onload = function () {
var data = iframe.contentWindow.name; //在这里我们得到了跨域页面中传来的数据
};
}
</script>
</head>
<body>
</body>
</html>
3)、JSONP方法
JONSP(JSON with Padding)是JSON的一种使用模式。基本原理如下:
<!-- a.html -->
<script>
function dealData (data) {
console.log(data);
}
</script>
<script src='http://example.com/data.php?callback=dealData'></script>
<!-- a.html -->
<script>
function dealData (data) {
console.log(data);
}
</script>
<script src='http://example.com/data.php?callback=dealData'></script>
这时候在a.html中我们得到了一条js的执行语句dealData(‘data’),从而达到了跨域的目的。
所以JSONP的原理其实就是利用引入script不限制源的特点,把处理函数名作为参数传入,然后返回执行语句,仔细阅读以上代码就可以明白里面的意思了。
如果在jQuery中用JSONP的话就更加简单了:
<script>
$.getJSON(''http://example.com/data.php?callback=?', function (data) {
console.log(data);
});
</script>
注意jQuery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用JSONP的回调函数。
24、 页面编码和被请求的资源编码如果不一致如何处理?
若请求的资源编码,如外引js文件编码与页面编码不同。可根据外引资源编码方式定义为 charset=“utf-8"或"gbk”。
比如:http://www.yyy.com/a.html 中嵌入了一个http://www.xxx.com/test.js
a.html 的编码是gbk或gb2312的。而引入的js编码为utf-8的 ,那就需要在引入的时候