zzhihang / blog Goto Github PK
View Code? Open in Web Editor NEWsth write here
sth write here
CORS基本**就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
发送一个请求时携带一个Origin头部,其中过包括请求页面的源信息(协议、域名和端口),浏览器之后会根据这个头部信息来决定是否给予响应。
比如: Origin:http://www.baidu.com
如果服务器认为这个请求可以接受,就会在Access-Control-Allow-Origin头部回发相同的源信息(如果是公共资源,可以回发"*")。例如:
Access-Control-Allow-Origin:http://www.baidu.com
如果没有这个头部,或者有这个头部但源信息不匹配,浏览器就会驳回请求。此时的请求和响应都不会包含cookie信息。
请求需要携带凭据怎么处理呢?
通过将withCredentials属性设置为true,可以指定某个请求携带凭据,同样的,如果服务器接受携带凭据的请求,会用下面的http头部响应。
Access-Control-Allow-Credentials: true
如果发送的是带凭据的请求,但服务器的响应中没有包含这个头部,那么浏览器就不会把响应交给JS处理(于是,resourceText中将是空字符串,status值为0,触发onError事件)
function jsonp(url, data, callback){
var callbackName = "callback_" + new Date().getTime();
window[callbackName] = callback;
data.callback = callbackName;
var params = [];
for (var key in data){
params.push(key + '=' + data[key])
}
var script = document.createElement('script');
script.src = url + '?' + params.join('&');
window[callbackName] = function (param) {//将传入的callback封装在内部并挂载在window身上
callback(param);
document.body.removeChild(script);
};
document.body.appendChild(script);
}
//返回promise
function jsonp2(url, data, callback){
var callbackName = "callback_" + new Date().getTime();
window[callbackName] = callback;
data.callback = callbackName;
var params = [];
for (var key in data){
params.push(key + '=' + data[key])
}
var script = document.createElement('script');
script.src = url + '?' + params.join('&');
document.body.appendChild(script);
return new Promise(function (resolve, reject) {
window[callbackName] = function (param) {
try {
resolve(param);
callback(param);
}catch (e) {
reject(param)
}finally {
document.body.removeChild(script);
}
};
});
}
jsonp2('https://photo.sina.cn/aj/index',{
page:1,
cate:'recommend',
},function(data){
console.log(data)
}).then(function (data) {
console.log(data)
})
var person = {
toString: function(){
return 'mr.zhu'
}
}
[person].toString() // mr.zhu
基本类型值不是对象,理论上不应该有方法,实际上在s被使用读取的过程中,代码内部会完成以下处理:
var s = new String('I am a string');
这个new的过程应该都很熟悉
宏队列,macrotask,也叫tasks。 一些异步任务的回调会依次进入macro task queue,等待后续被调用,这些异步任务包括:
微队列,microtask,也叫jobs。 另一些异步任务的回调会依次进入micro task queue,等待后续被调用,这些异步任务包括:
这里归纳3个重点:
console.log(1); //同步代码被执行 1
setTimeout(() => {
console.log(2); //进入宏队列
Promise.resolve().then(() => {
console.log(3) //进入微队列
});
});
new Promise((resolve, reject) => {
console.log(4) //new Prosmise的时候会执行此处
resolve(5)
}).then((data) => { //进入微队列
console.log(data);
})
setTimeout(() => {//进入宏队列
console.log(6);
})
console.log(7); //同步代码被执行 7
// 正确答案
1
4
7
5
2
3
6
console.log(1); //1
setTimeout(() => {
console.log(2);
Promise.resolve().then(() => { //注意此处then之后的回调作为微任务被添加到队列的末尾,需要将此处的微任务执行完毕才能执行下一个宏任务队列中的第一项;
//谨记这句话 在执行微队列microtask queue中任务的时候,如果又产生了microtask,那么会继续添加到队列的末尾,也会在这个周期执行,直到microtask queue为空停止。
console.log(3)
});
});
new Promise((resolve, reject) => {
console.log(4) //new Prosmise的时候会执行此处 4
resolve(5)
}).then((data) => {
console.log(data);
Promise.resolve().then(() => {
console.log(6)
}).then(() => {
console.log(7)
setTimeout(() => {
console.log(8)
}, 0);
});
})
setTimeout(() => {
console.log(9);
})
console.log(10);
// 正确答案
1
4
10
5
6
7
2
3
9
8
内容大部分学习自 带你彻底弄懂Event Loop
所有的构造函数都是Function的实例,包括Array, Function, Date, Object, Number内置构造函数
所以
Array.__proto__ === Function.prototype
Object.__proto__ === Function.prototype
Function.__proto__ === Function.prototype
var a = function(){}
a.__proto__ === Function.prototype 因为a也是Function的实例
var a = new Object();
a._proto = Object.prototype
所有的普通对象的__proto__都等于Object.prototype,因为所有的普通对象都可以看做是由构造函数构造出来的对象
原型链是向上搜索的,搜到最顶层没有的话就会返回undefined了
经过上面步骤,生成的a就有了构造函数的属性和方法
代码如何实现呢?(可以和上面new的过程自行连线)
function myNew(){
var obj = new Object();
var Constructor = [].shift.call(arguments)
obj._proto_ = Constructor.prototype;
var ret = Constructor.apply(obj, arguments);
return typeof ret === 'object' ? ret : obj; //处理构造函数是否有返回值
}
既然每一个实例对象的原型都可以访问到其构造函数的prototype属性, 因为构造函数prototype本身就保存了自身constructor,constructor指向构造函数方便自己访问自己的构造函数方法
因此
实例.constructor === 构造函数.prototype.constructor 这是实例通过访问自己的__proto__属性从而访问到其构造函数的prototype 自然也就拿到了constructor
function Base() {}
// Sub1 inherited from Base through prototype chain
function Sub1(){}
Sub1.prototype = new Base();
Sub1.prototype.constructor = Sub1;
Sub1.superclass = Base.prototype;
// Sub2 inherited from Sub1 through prototype chain
function Sub2(){}
Sub2.prototype = new Sub1();
Sub2.prototype.constructor = Sub2;
Sub2.superclass = Sub1.prototype;
// Test prototype chain
alert(Sub2.prototype.constructor);// function Sub2(){}
alert(Sub2.superclass.constructor);// function Sub1(){}
alert(Sub2.superclass.constructor.superclass.constructor);// function Base(){}
上面代码可以看出,一旦prototype整个对象发生重新赋值的话constructor属性就会发生变化
function F() {}
F.prototype = {
_name: 'Eric',
getName: function() {
return this._name;
}
};
初看这种方式并无问题,但是你会发现下面的情况:
var f = new F();
alert(f.constructor === F); // false
f.constructor === Object // true
f.constructor === Object.prototype.constructor //true
这是因为F.prototype被完全重写了,导致实例f通过__proto__查找到的只是重新赋值的对象字面量{};
由于{}是Object的实例,{}.__proto__指向了Object.prototype,此时原型链向上查找,最终f.constructor === Object.prototype.constructor, 由于prototype.constructor指向自身,所以f.constructor === Object;
只需要F.prorotype.constructor === F就行了
function createPig(weight, age){
var p = {};
p.weight = weight;
p.age = age;
p.sayWeight = function(){
return this.weight;
}
}
var person = createPig('zhu', 18);
优点:对象的封装,解决了创建相似对象的问题;
缺点:无法知道对象的类型,对象类型p始终继承自Object,原型链上只有Object.prototype。
function Pig(weight, age){
this.weight = weight;
this.age = age;
this.sayWeight = function(){
return this.weight;
}
}
var pig = new Pig(100, 1);
优点:能够识别对象类型,pig来自于其构造函数Pig;
缺点:实例会复制每个sayHungry方法,函数也是对象,相当于同时又实例化了多个对象。
function Pig(){
}
Pig.prototype.weight = '10';
Pig.prototype.sayWeight = function(){
return this.weight;
}
优点: 个人觉得没什么优点,反而写的更麻烦了,因为属性也是同样被共享了;
缺点:一般很少有人这样用吧,构造函数初始化的时候传入一些参数更好,于是也就有了构造函数+原型链的方法模式
function Pig(weight, age){
this.weight = weight;
this.age = age;
}
Pig.prototype = {
constructor: Pig;
sayWeight: function(){
return this.weight;
}
}
优点:灵活,共享属性和方法以及实例各自的属性都会被区分;
基本**为创建一个函数,函数的作用仅仅只是将创建对象的代码封装起来,然后返回新创建的对象,表面看来,和第一种模式很像;
function Person(weight, age){
var pig = {};
pig.weight = weight;
pig.age = age;
return pig;
}
假设有这样一个问题,在不破坏Array本身构造函数的情况下,如何创建一个同样拥有Array方法并可以扩展?
function MyArray(){
var array = [];
array.push.apply(array, arguments);
array.splitByLine = function(){
return this.join('|');
}
return array;
}
var myArray = new MyArray('zhu', 'zhi')
console.log(myArray.splitByLine());
var foo = {
value: 1
};
function bar(name, age) {
console.log(this.value)
console.log(name)
console.log(age)
return {
name: name
};
}
//bar.call(foo)
Function.prototype.myCall = function (context) {
context = context || window; //传入null的时候指向window
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push('arguments[' + i + ']') //使用字符串的原因是防止eval('context.fn(zhuzhihang, 18)'),会报zhuzhihang is not defined
}
//es6在此处就很简单了
// args = [...arguments].slice(1);
// context.fn(...args)
console.log(args) //[ 'arguments[1]', 'arguments[2]' ],这样在执行eval时,arguments[1]是作为一个真实变量存在的,
context.fn = this;
var result = eval('context.fn(' + args + ')');
delete context.fn;
return result;
};
var result = bar.myCall(foo, 'zhuzhihang', '18')
console.log(result)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.