/**1**/
var start = new Date();
setTimeout(function() {
console.log(new Date() - start);
}, 500);
while((new Date() - start) <= 1000){}
输出:?
// (不看下面那段代码 输出: >=500) 进程和线程:计算完后需要渲染时间
while((new Date() - start) <= 1000){} // 1000ms内死循环,没有含义但是在吃CPU
// js本身是单线程,1000ms内一直占用着线程,只有主线程空了才会执行任务队列,所以最后输出 >= 1000
/**2**/
var log = console.log;
var hint = window.alert;
var write = document.write;
log('123');
hint('123');
write('123');
// 分别输出什么?
// 123
// 123
// Uncaught TypeError: Illegal invocation
// write不是window方法,所以调用会报错
var document = {
write: function(htmlText) {
if (!(this instanceof document)) {
throw new TypeError("Illegal invocation");
}
this.body.appendChild(document.createTextNode(htmlText));
}
}
// 以上是伪代码,用于理解含义
腾讯面试题
var name = "A";
function getName() {
return this.name;
}
var obj = {
name: "B",
getName: function(){
return this.name;
},
showName: function(a) {
console.log(getName());
console.log(a());
console.log(this.getName());
console.log(arguments[0]());
}
}
obj.showName(getName, 1);
// 输出 A A B undefined
// arguments 的this里没有name,所以输出undefined
console.log(arguments[0]().call(window)); // 这样输出 A
据说是小米面试题
// 说出以下函数的作用是?空白区域应该填写什么?
(function (window) {
function fn(str) {
this.str = str;
}
fn.prototype.format = function () {
var arg = ______;
return this.str.replace(______, function (a, b) {
return arg[b] || "";
});
}
window.fn = fn;
})(this);
//user
(function () {
var t = new fn('{1}{2}
');
console.log(t.format('http://www.alibaba.com','Alibaba','Welcome'));
})();
答案:
(function (window) {
function fn(str) { // 构造函数 str = '{1}{2}
'
this.str = str; // this.str t.str
}
fn.prototype.format = function () { // 实例对象 封装format方法
var arg = arguments;
return this.str.replace(/^\{(\d+)\}$/g, function (a, b) { //{0} {1} {2}
return arg[b] || ""; // a:正则模式 b:此正则模式中的表达式 0 1 2
});
}
window.fn = fn;
})(this);
//user
(function () {
var t = new fn('{1}{2}
'); // 创建实例对象
console.log(t.format('http://www.alibaba.com','Alibaba','Welcome'));
})();
来自国外的一道题
JavaScript (a ==1 && a== 2 && a==3) 可能为 true 吗???
/* 这是国外一位求职者在最近一家大型科技公司面试时遇到的一个问题,他的回答是「不可能」
* 而面试官说「nothing is impossible」,这个问题在 Stack Overflow 上提出后,短短 3 天,访问量和答案让人很是惊喜
*/
// 答案1:
const a = {
i: 1,
toString: function () {
return a.i++;
}
}
if(a == 1 && a == 2 && a == 3) {
console.log('Hello World!');
}
// 答案2:
var i = 0;
with({
get a() {
return ++i;
}
}) {
if (a == 1 && a == 2 && a == 3) {
console.log("wohoo");
}
}
// 答案3:
a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3);
/*
* This works because == invokes toString which calls .join for Arrays.
* Another solution, using Symbol.toPrimitive which is an ES6 equivalent of toString/valueOf:
*/
let a = {[Symbol.toPrimitive]: ((i) => () => ++i) (0)};
console.log(a == 1 && a == 2 && a == 3);
// 答案4
var val = 0;
Object.defineProperty(window, 'a', {
get: function() {
return ++val;
}
});
if (a === 1 && a === 2 && a === 3) {
console.log('yay');
}
// 这个做法可以用全等号
// https://stackoverflow.com/questions/48270127/can-a-1-a-2-a-3-ever-evaluate-to-true
一道经典面试题:
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 先查栈中有没有getName变量,如果存在并且有引用 则输出,如果栈中的变量没有引用则从堆中查找
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3
// 答案说明 http://web.jobbole.com/85122/
杂
// 不用临时变量交换2个值
function swap(a, b) {
b = b - a;
a = a + b;
b = a - b;
return [a, b];
}
// 交换数组内2个下标的值
arr.splice(x - 1, 1, …arr.splice(y - 1, 1, arr[x - 1]))
1.JS数据类型有哪些?哪些是引用类型?
Undefined、Null、Boolean、Number和String。还有1种复杂的数据类型————Object
Undefined、Null、Boolean、Number都属于基本类型。Object、Array和Function则属于引用类型
详细说明
console.log({}.length) // undefined
console.log(({}+{}).length) // 30
// {}+{} 为[object Object][object Object] ,对象本身没有加法操作 所以 js类型转换后变成30个字符
2.CSS优先级
ID>class>元素选择器 行内样式>内页样式>外部样式
link、:visited、:hover、:active
//这四个伪类如果对同一个元素设置同一个属性,那它们的声明顺序还有一定要求,一般都遵循“爱恨原则LVHA”(LoVe HAte)
3.前端性能优化指标:
首屏加载速度,页面加载速度,响应速度
4.移动端click :
touchstart, touchmove, touchend, 以及tappc端有mousedown, mousemove, mouseup, click
5.ajax readyState 5种状态
0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
6.用递归写一个阶乘函数
function test(a){
if(a==1){
return 1;
}else{
return arguments.callee(a-1)*a
}
}
7.Promise的优点
解决了回调地狱!Promise 本质上是分离了异步数据获取和业务逻辑,从而让开发人员能专注于一个事物,而不必同时考虑业务和数据。
缺点:首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
// 第一部分 数据获取和加工阶段
var getUserName = function(){
return new Promise(function(resolve,reject){
$.get('xxx.com/getUserName',function(data){
resolve(data);
});
};
var getMobile = function(userName){
return new Promise(function(resolve,reject){
$.get('xxx.com/getUserMobile?user='+userName,function(data){
resolve(data);
});
});
}
// 第二部分 业务逻辑部分
getUserName().then(function(userName){
return getMobile(userName);
}).then(function(mobile){});
8.如何解决跨域问题?
jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面
- document.domain + iframe:要求主域名相同 //只能跨子域
- JSONP(JSON with Padding):response: callback(data) //只支持 GET 请求
- 跨域资源共享CORS(XHR2):Access-Control-Allow //兼容性 IE10+
- 跨文档消息传输(HTML5):postMessage + onmessage //兼容性 IE8+
- WebSocket(HTML5):new WebSocket(url) + onmessage //兼容性 IE10+
- 服务器端设置代理请求:服务器端不受同源策略限制
9.实现bind方法
Function.prototype.bind = function (context) {
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var result = function () {
var bindArgs = Array.prototype.slice.call(arguments);
// 如果this intanceof result 为 true 代表了构造函数场景
return self.apply(this instanceof result ? this : context, args.concat(bindArgs)); // 当针对方法操作的时候一定要考虑返回值,return出去
}
result.prototype = this.prototype;
return result;
}