非常感谢,前同事行长
@onlyadaydreamer分享的面经。
其实每次与产品同学的争论都是无意义的,因为我们始终怼不过她们😭😭😭
不过还好,中午打游戏的时候,公司5V5,把UI和产品杀穿了,😤😤😤
继续正文
前端xss攻击和防御
前端xss攻击和防御 欢迎点击收藏 👏 👏 👏
jquery.ready方法实现原理
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
//这里的setTimeout是为了异步
setTimeout( jQuery.ready, 1 );
// Standards-based browsers support DOMContentLoaded
//标准浏览器侦听事件接口:document.addEventListener
} else if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
//文章一开始说了,这里为了保证一定会触发ready,所以还针对onload也绑定一次回调
window.addEventListener( "load", jQuery.ready, false );
// If IE event model is used
} else {
//IE侦听事件接口:document.attachEvent
//如果有onreadystatechange事件,侦听之
// Ensure firing before onload, maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// A fallback to window.onload, that will always work
window.attachEvent( "onload", jQuery.ready );
// http://javascript.nwbox.com/IEContentLoaded/
// 见下边说明
// If IE and not a frame
// continually check to see if the document is ready
var top = false;
try {
top = window.frameElement == null && document.documentElement;
} catch(e) {}
//如果是IE并且不是iframe
if ( top && top.doScroll ) {
(function doScrollCheck() {
if ( !jQuery.isReady ) {
try {
// Use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
//一直调用doScroll滚动,因为DOM渲染结束前,DOM节点是没有doScroll方法的,所以一直会异常
//直到DOM渲染结束了,这个时候doScroll方法不会抛出异常,然后就调用$.ready()
top.doScroll("left");
} catch(e) {
return setTimeout( doScrollCheck, 50 );
}
// and execute any waiting functions
jQuery.ready();
}
})();
}
}
知道Symbol吗?有什么作用?
根据规范,对象的属性键只能是字符串类型或者 Symbol 类型。不是 Number,也不是 Boolean,只有字符串或 Symbol 这两种类型。
Symbol 保证是唯一的。即使我们创建了许多具有相同描述的 Symbol,它们的值也是不同。描述只是一个标签,不影响任何东西。
例如,这里有两个描述相同的 Symbol —— 它们不相等:
let id1 = Symbol("id");
let id2 = Symbol("id");
alert(id1 == id2); // false
注意:Symbol 不会被自动转换为字符串
JavaScript 中的大多数值都支持字符串的隐式转换。例如,我们可以 alert 任何值,都可以生效。Symbol 比较特殊,它不会被自动转换 。 例如,这个 alert 将会提示出错:
let id = Symbol("id");
alert(id); // 类型错误:无法将 Symbol 值转换为字符串。
复制代码这是一种防止混乱的“语言保护”,因为字符串和 Symbol 有本质上的不同,不应该意外地将它们转换成另一个。
如果我们真的想显示一个 Symbol,我们需要在它上面调用 .toString(),如下所示:
let id = Symbol("id");
alert(id.toString()); // Symbol(id),现在它有效了
复制代码或者获取 symbol.description 属性,只显示描述(description):
let id = Symbol("id");
alert(id.description); // id
Symbol 允许我们创建对象的“隐藏”属性,代码的任何其他部分都不能意外访问或重写这些属性。
例如,如果我们使用的是属于第三方代码的 user 对象,我们想要给它们添加一些标识符。
我们可以给它们使用 Symbol 键:
let user = { // 属于另一个代码
name: "John"
};
let id = Symbol("id");
user[id] = 1;
alert( user[id] ); // 我们可以使用 Symbol 作为键来访问数据
手写一个ajax
function get(url,data,callback){
let paramArr = [];
let encodeData;
if (data instanceof Object) {
for (let key in data) {
// 参数拼接需要通过 encodeURIComponent 进行编码
paramArr.push( encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) )
}
encodeData = paramArr.join('&')
}
url += encodeData;
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
//如果是IE5或者IE6浏览器,则使用ActiveX对象
xhr = ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open('GET',url,true)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status == 200 || xhr.status == 304){
callback(response)
}
}
xhr.send(null)
}
function post(url,data,callback){
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
//如果是IE5或者IE6浏览器,则使用ActiveX对象
xhr = ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open('POST',url,true)
xhr.setRequestHeader('Content-Type':"application/x-www-form-urlencoded")
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200 || xhr.status === 304){
callback(response)
}
}
xhr.send(data)
}
深拷贝和浅拷贝
可以参考我的这个文档深拷贝和浅拷贝