web细节面试相关

前端面试题总结

2016-11-22  本文已影响52人  darr250

1. 使用事件代理是避免什么性能问题?

js绑定事件对性能的影响:

2. 写一个requirejs的加载机制

之前总结的

function loadScript(url, callback){
  var script = document.createElement ("script")
  script.type = "text/javascript";
  if (script.readyState){ //IE
    script.onreadystatechange = function(){
      if (script.readyState == "loaded" || script.readyState == "complete"){
        script.onreadystatechange = null;
        callback();
      }
    };
  } else { //Others
    script.onload = function(){
      callback();
    };
  }
    script.src = url;
    document.getElementsByTagName_r("head")[0].appendChild(script);//即插即执行
}

4. cookie expire有几种设置

https://developer.mozilla.org/zh-CN/docs/Web/API/Document/cookie
过期:

//永久cookie
; expires=Fri, 31 Dec 9999 23:59:59 GMT
>Note: 对于永久cookie我们用了Fri, 31 Dec 9999 23:59:59 GMT
作为过期日。如果你不想使用这个日期,可使用*[世界末日](http://en.wikipedia.org/wiki/Year_2038_problem)*Tue, 19 Jan 2038 03:14:07 GMT,
它是32位带符号整数能表示从1 January 1970 00:00:00 UTC开始的最大秒长(即01111111111111111111111111111111
, 是 new Date(0x7fffffff * 1e3)
).

//删除cookie
function deleteCookie(name){
    var name = escape(name);
    var expires = new Date(0);//1970
    var path = ";path=/";
 document.cookie = name + "="+ ";expires=" + expires.toUTCString() + path;
}

5. 本地存储

特性 Cookie localStorage sessionStorage
数据的生命期 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 除非被清除,否则永久保存 仅在当前会话下有效,关闭页面或浏览器后被清除
存放数据大小 4K左右 一般为5MB -
与服务器端通信 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 仅在客户端(即浏览器)中保存,不参与和服务器的通信 -
易用性 需要程序员自己封装,源生的Cookie接口不友好 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 -

两个storage其他属性方法都一样

特性 Cookie localStorage sessionStorage
数据的生命期 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 除非被清除,否则永久保存 仅在当前会话下有效,关闭页面或浏览器后被清除
存放数据大小 4K左右 一般为5MB -
与服务器端通信 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 仅在客户端(即浏览器)中保存,不参与和服务器的通信 -
易用性 需要程序员自己封装,源生的Cookie接口不友好 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 -

有了对上面这些差别的直观理解,我们就可以讨论三者的应用场景了。

6. 使用CORS还会带cookie么

JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象,当然无法读取cookie了。
使用CORS是可以的:跨域资源共享 CORS 详解
Access-Control-Allow-Credentials
该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true
,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true
,如果服务器不要浏览器发送Cookie,删除该字段即可。

7. 介绍原型链原理

JavaScript核心 - 博客 - 伯乐在线

如果一个属性或者一个方法在对象自身中无法找到(也就是对象自身没有一个那样的属性),然后它会尝试在原型链中寻找这个属性/方法。如果这个属性在原型中没有查找到,那么将会查找这个原型的原型,以此类推,遍历整个原型链(当然这在类继承中也是一样的,当解析一个继承的方法的时候-我们遍历class链( classchain))。

注意: ES5标准化了一个实现原型继承的可选方法,即使用Object.create函数:
1 var b = Object.create(a, {y: {value: 20}});

2 var c = Object.create(a, {y: {value: 30}});

你可以在对应的章节获取到更多关于ES5新API的信息。 ES6标准化了 proto属性,并且可以在对象初始化的时候使用它。

8. this的几种指向

参考:javascript中的this

  1. this指向的是当前调用该函数的对象
function test(){ console.log(this) } //直接调用 test()// 输出对象为window,在nodejs中输出为global
  1. 作为对象方法的调用:函数还可以作为某个对象的方法调用,这时this就指这个上级对象。
  2. 作为构造函数调用: this指向实例
  3. apply调用: apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。

8.1 构造函数中有return 的话,this的指向是?

使用new关键字实例化的时候发生了什么?

function Prince(name,age){
    this.gender="male";
    this.kind=true;
}
Prince.prototype.toFrog=function(){
    console.log("Prince "+this.name+" turned into a frog.");
}
var prince=new Prince("charming",25);

以上文中的Prince()函数举个栗子[重要]:

  1. 第一步,创建一个空对象。var prince={}
  2. 第二步,将构造函数Prince()中的this指向新创建的对象prince
  3. 第三步,将prince的proto属性指向Prince函数的prototype,创建对象和原型间关系
  4. 第四步,执行构造函数Prince()内的代码。

构造函数有return值怎么办?
构造函数里没有显式调用return时,默认是返回this对象,也就是新创建的实例对象。
当构造函数里调用return时,分两种情况:

  1. return的是五种简单数据类型:String,Number,Boolean,Null,Undefined。
    这种情况下,忽视return值,依然返回this对象。[和没有return一样]
    其中的this指向如下所示:
function O(name){
  console.log(this);//{}
  this.name = name;
  console.log(this);//{name:"f"}
}
var oo = new O("f");
console.log(oo);//{name:"f"}
  1. return的是Object: 这种情况下,不再返回this对象,而是返回return语句的返回值。
    其中的this,如注释所示:
function O(name){
  console.log(this);//{}
  this.name = name;
  console.log(this);//{name:"f"}
  return {};
}
var oo = new O("f");
console.log(oo);//{}

4. call 和 apply

call调用的是apply.

5. jsbridge

我们使用的是jsbridge:使用WebViewJavascriptBridge与JS交互
WebViewJavascriptBridge是一个轻量的用于OC与JS交互的第三方库
参考:JSBridge——Web与Native交互之iOS篇
下面是jsbridge的原理:

UIWebView是iOS内置的浏览器控件,UIWebView用于在APP中嵌入网页,通常是html网页,也可以是PDF、txt文档等。但需要注意的是,Safari浏览器使用的浏览器控件和UIwebView组件并不是同一个,两者在性能上有很大的差距。幸运的是,苹果发布iOS8的时候,新增了一个WKWebView组件,如果你的APP只考虑支持iOS8及以上版本,那么你就可以使用这个新的浏览器控件了。

  1. Native(Objective-C或Swift)调用Javascript方法
    Native调用Javascript语言,是通过UIWebView组件的stringByEvaluatingJavaScriptFromString方法来实现的,该方法返回js脚本的执行结果。
    // Swiftwebview.stringByEvaluatingJavaScriptFromString("Math.random()")// OC[webView stringByEvaluatingJavaScriptFromString:@"Math.random();"];
  2. Javascript调用Native(Objective-C或Swift)方法
    “Native调用Web”本质上是JavaScript脚本的动态执行,在“Web调用Native”的场景下由于目前Native语言(Java和Objective-C)不容易像JavaScript那样便于动态执行,所以需要另辟蹊径。
    Javascript调用Native,并没有现成的API可以直接拿来用,而是需要间接地通过一些方法来实现。UIWebView有个特性:在UIWebView内发起的所有网络请求,都可以通过delegate函数在Native层得到通知。这样,我们就可以在UIWebView(嵌的我们的html)内发起一个自定义的网络请求,通常是这样的格式:jsbridge://methodName?param1=value1&param2=value2

于是在UIWebView的delegate函数中,我们只要发现是jsbridge://开头的地址,就不进行内容的加载,转而执行相应的调用逻辑。

【Js 使用了两种方式来与 Objective-C 通信,一种是使用 XMLHttpRequest 发起请求的方式,另一种则是通过设置透明的 iframe 的 src 属性。】
首先通过iframe发起一个网络请求,这个请求的作用是唤起Native APP的分享组件,将网页分享到朋友圈或分享给其他好友。
然后Webview就可以拦截这个请求,并且解析出相应的方法和参数,执行相应的操作
在 native 执行完相应调用后,可以用stringByEvaluatingJavaScriptFromString 方法,将执行结果返回给 js.

更好的总结: http://www.blogs8.cn/posts/Wijg6e6

同步和异步

因为 iOS SDK 没有天生支持 js 和 native 相互调用,大家的技术方案都是自己实现的一套调用机制,所以这里面有同步异步的问题。细心的同学就能发现,js 调用 native 是通过插入一个 iframe,这个 iframe 插入完了就完了,执行的结果需要 native 另外用 stringByEvaluatingJavaScriptFromString 方法通知 js,所以这是一个异步的调用。
而 stringByEvaluatingJavaScriptFromString 方法本身会直接返回一个 NSString 类型的执行结果,所以这显然是一个同步调用。
所以 js call native 是异步,native call js 是同步。在处理一些逻辑的时候,不可避免需要考虑这个特点。

Ios Android Hybrid app 与 Js Bridge

将要发送的消息存放在Js端——>调用iframe.src,触发通知Native——>Native拦截请求,调用Js bridge里面的fetchQueue并获取返回的消息内容,处理消息——>将需要返回的数据通过直接调用Js的方式,让Js处理

重点: 最后一步我觉得可能是js发的调用native的请求里,还js里定义的callback。然后native直接执行这个callback。

上一篇下一篇

猜你喜欢

热点阅读