一、ajax原理是什么?ajax如何实现跨域?原理及过程?
Q1:Ajax的工作原理:通过XmlHttpRequest对象向服务器发送异步请求,从服务器获得数据,然后用JavaScript来操作DOM来更新页面。
Q2:
在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,可以通过以下几种方式实现跨域。
1)jsonp
原理:通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的回调函数,并且会把我们需要的json数据作为参数传入。jsonp需要服务器端的页面进行相应的配合。
2)document.domain(只适用于不同子域之间的交互)
原理:当两个页面的主域相同时,可以将这两个页面的document.domain都设成相同的域名,该域名必须是自身或者更高一级的父域。例如可以在页面 http://example.com/a.html和页面http://example.com/b.html中分别设置document.domain为example.com。这时候就可以ajax方法让不同子域两个页面交互了。
3)window.name(适用于同一个窗口生命周期内不同域之间的交互)
原理:在被请求页面设置内设置window.name为想获取的数据值。在请求页面中设置一个隐藏的iframe去获取被请求页面的数据,这时候需要把iframe的src设置为被请求页面的src。iframe获取到window.name中的数据后,将src改为与请求页面处于同一个域中的src,请求页面就可以访问iframe中的window.name的属性。
4)window.postMessage(适用于一个页面中有几个iframe进行交互的情况)
在被请求页面使用window.postMessage(message,targetOrigin) 。
调用postMessage方法的window对象是指被请求消息(发送消息)的那一个window对象,该方法的第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrigin用来限定请求消息的window对象所在的域,如果不想限定域,可以使用通配符 * 。
在请求页面,请求消息的window对象,可通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中。
5)服务器上设置代理页面
参考博文
二、js有一个单独的方法实现继承是什么?
call , apply实现继承
格式:
1.父级构造函数名call(this,参数1,参数2…)
2.父级构造函数名apply(this,[参数1,参数2…])或父级构造函数名apply(this,arguments)
<SPAN style="FONT-SIZE: 18px"><html>
<body>
<script type="text/javascript">
function Person(name,age,love){
this.name=name;
this.age=age;
this.love=love;
this.say=function say(){
alert("姓名:"+name);
}
}
//call方式
function student(name,age){
Person.call(this,name,age);
}
//apply方式
function teacher(name,love){
Person.apply(this,[name,love]);
//Person.apply(this,arguments); //跟上句一样的效果,arguments
}
//call与aplly的异同:
//1,第一个参数this都一样,指当前对象
//2,第二个参数不一样:call的是一个个的参数列表;apply的是一个数组(arguments也可以)
var per=new Person("武凤楼",25,"魏荧屏"); //输出:“武凤楼”
per.say();
var stu=new student("曹玉",18);//输出:“曹玉”
stu.say();
var tea=new teacher("秦杰",16);//输出:“秦杰”
tea.say();
</script>
</body>
</html></SPAN>
三、事件代理原理,优点是什么?
原理:利用事件冒泡机制,为父级DOM节点指定事件处理程序,来处理子级DOM节点的事件。
优点:
1)减少了事件处理程序的数量,占用内存更少;
2)为指定事件处理程序导致的访问DOM节点次数减少,页面的交互就绪时间缩短。
四、数组循环一般使用什么方法?
1、for循环:最简单的一种,也是使用频率最高的一种,虽然性能不弱,但仍有优化空间。
for(i= 0;i< arr.length;i++) {
}
使用临时变量,保存数组长度,避免重复获取数组长度,当数组较大时优化效果比较明显。
for(i= 0,len=arr.length;i < len;i++) {
}
2、foreach循环:数组自带的foreach循环,性能比普通for循环弱
arr.forEach(function(e){
});
3、for/in循环:用于处理稀疏数组。遍历数组的属性(包括继承自原型的属性、数组索引)。
for(index in arr) {
}
五、call,apply的区别?
二者均用于间接调用函数,把指定函数当成指定对象的方法来调用。
call()用参数列表的形式传参。call()的第一个参数是调用函数的对象,后面的参数是参数列表。
apply()用数组的形式传参。apply()的第一个参数是调用函数的对象,第二个参数是个参数数组。
六、call,bind的区别
call():间接调用函数,把指定函数当成指定对象的方法来调用。需要显式地指定对象、要调用的函数和函数的实参。
bind():将函数绑定到某个对象,返回一个新函数,调用新函数会把指定函数当成指定对象的方法来调用。显式地指定对象,要绑定的函数和函数的实参。除了第一个实参外,传入bind的实参也会绑定到指定对象上(函数柯里化)。
七、setTimeout(function(){console.log(1)},0) console.log(2)哪个先执行?
先执行外面的,再里面的。
javascript都是以单线程的方式运行于浏览器的javascript引擎中的, setTimeout的作用只是在到达设定的时间后把要执行的代码插入js引擎维护的一个任务队列中执行。js引擎在主线程方法执行完毕,到达空闲状态时,会从任务队列中顺序获取任务来执行,这一过程是一个不断循环的过程,称为事件循环模型。
从setTimeout说事件循环模型
setTimeout和setInterval的区别你真的了解吗?
八、setTimeout,setInterval的区别?能否用setTimeout实现setInterval?实现了后与setInterval有什么区别?
Q1:前者只执行一次,后者循环执行。
Q2:在setTimeout里嵌套一个setTimeout。
setTimeout(function(){
//processing 定时器内的代码块
setTimeout(arguments.callee, interval); //callee 是 arguments 对象的一个属性。它可以用于引用该函数的函数体内当前正在执行的函数。
}, interval);
Q3:js引擎的任务队列中只能保存一个未执行的定时器代码块。如果定时器内的代码块执行时间大于setInterval()方法的定时间隔,会出现已经到达定时间隔但任务队列里还有未执行的定时器代码块的情况,这时候要插入的代码块不会加入任务队列,而是被直接跳过。
嵌套的setTimeout()定时器不会出现该问题。
九、手写jsonp的实现
以查询航班信息为例,客户端代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
// 得到航班信息查询结果后的回调函数
var flightHandler = function(data){
alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
};
// 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
// 创建script标签,设置其属性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
</script>
</head>
<body>
</body>
</html>
服务端代码(后端负责,前端不用管):
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
核心代码总结:
1)创建回调函数,处理回调函数的查询结果。
2)创建url,在url中设置回调函数
3)创建script标签,设置其src属性为url
4)将script标签加入<head>标签中
...
<head>
<script type="text/javascript">
var jsonpCallback=function(data){
alert('我是本地函数,远程js带来的数据是:' + data.result);
};
var url="http://JsonpQuery.com/jsonp/JsonpResult?callback=jsonpCallback";
var script=document.createElement('script');
script.setAttribute('src',url);
document.getElementsByTagName('head')[0].appendChild(script);
</script>
</head>
...
参考博文:
jsonp原理详解——终于搞清楚jsonp是啥了
十、原型链的解释
将子代的构造函数的原型设置为父代构造函数的一个对象实例,就构成了原型链。子代的对象实例除了可以调用自身的属性和方法,还可以沿着原型链调用自身没有但是父代有的属性和方法。
网友评论