实现var a=add(2)(3)(4);//9
第一种方式:
function add(a) {
var temp = function (b) {
return add(a + b);
}
temp.valueOf = function () {
return a;
}
return temp;
}
var result=add(2)(3)(4);
console.log(result);
第二种方式:
function add(){
var args=Array.prototype.slice.call(arguments);
var fn=function(){
var fnArgs=Array.prototype.slice.call(arguments);
return add.apply(null,args.concat(fnArgs));
}
fn.valueOf=function(){
return args.reduce(function(a,b){
return a+b;
})
}
return fn;
}
var result=add(2)(3)(4);
console.log(result);
第三种方式
let add=(...a)=>{
let helper=(...b)=>{
return add(...[...a,...b]);
};
helper.valueOf=()=>{
let sum=0;
for(let item of a){
sum+=item;
}
return sum;
}
return helper;
};
var result=add(2)(3)(4);
console.log(result);
第四种方式:
function add(num){
num+=~~add;
add.num=num;
return add;
}
add.valueOf=function(){
return add.num;
}
var result=add(2)(3)(4);
console.log(result);
这里需要说明一下的是:
String类型的toString 方法需要存在并且返回原始类型,那么如果返回的不是一个原始类型,则会去继续寻找对象的 valueOf 方法
Function类型转换:与 Number 转换类似,如果函数的 valueOf 方法返回的不是一个原始类型,会继续找到它的 toString 方法.
判断是否为数组
if(typeof Array.isArray==="undefined")
{
Array.isArray = function(arg){
return Object.prototype.toString.call(arg)==="[object Array]"
};
}
解释代码
var a;
alert(typeof a); // undefined Undefined是一个只有一个值的数据类型,这个值就是“undefined”,在使用var声明变量但并未对其赋值进行初始化时,这个变量的值就是undefined
alert(b); // 报错 由于未声明将报错
var c = null;
alert(typeof c); //object null是一个只有一个值的数据类型,这个值就是null。表示一个空指针对象,所以用typeof检测会返回”object”
[] == false; // true
[] == ![]; // true 尝试将Object转换成number或string,取决于另外一个对比量的类型
实现随机选取10--100之间的10个数字,存入一个数组,并排序
var iArray = [];
function getRandom(istart, iend){
//选择的区间
var iChoice = iend - istart + 1;
//乘上区间加上起始位
return Math.floor(Math.random() * iChoice + istart);
}
for (var i = 0; i < 10; i++) {
iArray.push(getRandom(0, 200));
}
iArray.sort(function(a,b){
return a-b;
});
arguments、callee、caller
arguments.length是实参的个数
function inner(){
console.log(arguments.callee);//--callee放回正在执行的函数本身的引用 指向拥有这个arguments对象的函数,即inner()
console.log(arguments.callee.caller);//--这里是callee.caller 这个属性保存着调用当前函数的函数的引用,即outer()
console.log(inner.caller);//[Function: outer]
}
function outer(){
inner();
}
outer();
//严格模式下,不允许访问arguments.callee和arguments.caller属性
‘use strict‘;
// 两次都是1
void function fn(a) {
console.log(arguments[0]);//1
a = 2;
console.log(arguments[0]);//1
}(1);
找出数组中的最大值
//第一种方法
var a=[1,2,3,6,5,4];
var max=Math.max.apply(null,a);
console.log(max);
//第二种方法
var a=[1,2,3,6,5,4];
var max=eval(‘Math.max(‘+a.toString()+‘)‘);
console.log(max);
斐波那契数列
function* fib(n){
let [a,b]=[1,1];
while(n--){
yield a;
[a,b]=[b,a+b];
}
}
for(let item of fib(5)){
console.log(item);
}
判断一个字符串中出现次数最多的字符,并统计次数
var s = ‘aaabbbcccaaabbbaaabbbbbbbbbb‘;
var a = s.split(‘‘);
a.sort();
//排序之后就变成了["a", "a", "a", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "c", "c", "c"]
s = a.join(‘‘);
var pattern = /(w)1*/g;
//正则表达式中的小括号"()"。是代表分组的意思。 如果再其后面出现1则是代表与第一个小括号中要匹配的内容相同。
//注意:1必须与小括号配合使用
var ans = s.match(pattern);
//ans 这时候就变成了 ["aaaaaaaaa", "bbbbbbbbbbbbbbbb", "ccc"]
ans.sort(function(a, b) {
return a.length < b.length;
});;
console.log(ans[0][0] + ‘: ‘ + ans[0].length);
把queryString转换成js对象
function getQueryObject(url){
url=url==null?window.location.href:url;
var search=url.substring(url.lastIndexOf("?")+1);
var obj={};
var reg=/([^?&=]+)=([^?&=]*)/g;
search.replace(reg,function(rs,$1,$2){
var name=decodeURIComponent($1);
var val=decodeURIComponent($2);
obj[name]=String(val);
return rs;
})
return obj;
}
getQueryObject("http://www.cnblogs.com/zichi/p/4359786.html?aa=111&bb=3dadsads&43=43a");
//输出结果为{43: "43a", aa: "111", bb: "3dadsads"}
js闭包问题
function fun(n,o) {
console.log(o)
return {
fun:function(m){
return fun(m,n);
}
};
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
//问:三行a,b,c的输出分别是什么?
//答案:
//a: undefined,0,0,0
//b: undefined,0,1,2
//c: undefined,0,1,1
prototype问题
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
//答案:
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3
各浏览器内核
alt和title的区别
alt用来指定替换文字,只能用在img、area和input元素中(包括applet元素),用于网页中图片无法正常显示时给用户提供文字说明使其了解图像信息
title用来为元素提供额外说明信息,举例来说:给超链接标签a添加了title属性,把鼠标移动到该链接上面时,就会显示title的内容,以达到补充说明或者提示的效果
强调的是:alt 在ie7下使用在img标签上 确实跟使用title的效果一样
strong和em标签的区别
strong粗体强调标签,强调表示内容的重要性
em斜体强调标签,更强烈的强调,表示内容的强调点
渐近增强和优雅降级 ##
利用多个域名来存储网站资源会更有效
CDN缓存更方便
突破浏览器并发限制
节约cookie带宽
节约主域名的连接数,优化页面响应速度
防止不必要的安全问题
src和href的区别
src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。
src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。
href是Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,如果我们在文档中添加<link href="common.css" rel="stylesheet"/>那么浏览器会识别该文档为css文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用link方式来加载css,而不是使用@import方式。
优化图片加载方式
图片懒加载,在页面上的未可视区域可以添加一个滚动条事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载。
如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载。
如果图片为css图片,可以使用CSSsprite,SVGsprite,Iconfont、Base64等技术。
如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。
如果图片展示区域小于图片的真实大小,则因在服务器端根据业务需要先行进行图片压缩,图片压缩后大小与展示一致。
跨域通信 ##
js定义方法的方法 ##
一般性的用Object.create创建对象会比较少用
自己实现bind方法
Function.prototype.bind=Function.prototype.bind||function(context){
var self=this;
return function(){
return self.apply(contex,arguments);
};
}
HTTP Method一般有哪几种 ##
display:none和visiblity:hidden区别 ##
第四个区别点怎么理解呢:如果display:none的容器中如果有img 则它的background-image都不会请求相应的资源,而visibility会请求
web安全及防护
参考文献:
BAT及各大互联网公司2014前端笔试面试题--Html,Css篇
BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
这10道javascript笔试题你都会么
大部分人都会做错的经典JS闭包面试题
一道常被人轻视的前端JS面试题
/bVQYiH