22:冒泡排序
var arr = [1,4,-8,-3,6,12,9,8]; function bubbleSort(arr){ for (var i = 0; i < arr.length; i++) { for (var j = 0; j < arr.length-i-1; j++) { if(arr[j] > arr[j+1]){ var c = arr[j]; arr[j] = arr[j+1]; arr[j+1] = c; } } } return arr; } console.log(bubbleSort(arr));
23:原型链的理解:
在谈原型链之前,我们首先要了解自定义函数与 Function 之间是什么关系,而构造函数、原型和实例之间又存在什么
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QqhVpWo7-1630416218424)(en-resource://database/450:1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8tp8hnPS-1630416218430)(en-resource://database/452:1)]
1、原型链 1)构造函数、原型和实例的关系 ①构造函数都有一个属性prototype,这个属性是一个对象(Object的实例) ②原型对象prototype里面有一个constructor属性,该属性指向原型对象所属的构造函数 ③实例对象都有一个_proto_属性,该属性也指向构造函数的原型对象,它是一个非标准属性, 不可以用于编程,它是用于浏览器自己使用的 2)prototype与_proto_的关系 ①prototype是构造函数的属性 ②_proto_是实例对象的属性 ——这两者都指向同一个对象 【总结】 i)函数也是对象,对象不一定是函数; ii)对象的本质:无序的键值对集合;键值对当中的值可以是任意数据类型的值 iii)对象就是一个容器,这个容器当中放的是(属性和方法) 3)属性搜索 ①在访问对象的某个成员的时候会先在对象中找是否存在 ②如果当前对象中没有就在构造函数的原型对象中找 ③如果原型对象中没有找到就到原型对象的原型上找 ④知道Object的原型对象的原型是null为止 2、Function—— 所有函数都是Function的实例 `①本地对象:独立于宿主环境(浏览器)的对象——包括Object、Array、Date、RegExp、 Function、Error、Number、String、Boolean ②内置对象——包括Math、Global(window,在js中就是全局变量),使用的时候不需要 new ③宿主对象——包括自定义对象、DOM、BOM
24:改变this指向的方法
第一种: new关键字改变this指向 function Fn(){ this.user = "追梦子"; } var a = new Fn(); console.log(a.user); //追梦子 用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份第二种: call()
第二种: call() var a = { user:"追梦子", fn:function(){ console.log(this.user); //追梦子 } } var b = a.fn; b.call(a); //若不用call,则b()执行后this指的是Window对象 把b添加到第一个参数的环境中,简单来说,this就会指向那个对象。
第三种:apply() var a = { user:"追梦子", fn:function(){ console.log(this.user); //追梦子 } } var b = a.fn; b.apply(a);
第四种:bind() var a = { user:"追梦子", fn:function(){ console.log(this.user); } } var b = a.fn; b.bind(a); //代码没有被打印 我们发现代码没有被打印,对,这就是bind和call、apply方法的不同,实际上bind方法返回的是一个修改过后的函数。
25:es6新特性
1. 变量声明 let 与 const: 可以把let看成var,只是它定义的变量被限定在了特定范围内才能使用,而离开这个范围则无效。const则很直观,用来定义常量,即无法被更改值的变量。 for (let i=0;i<2;i++)console.log(i);//输出: 0,1 console.log(i);//输出:undefined,严格模式下会报错
2.类的支持 ES6中添加了对类的支持,引入了class关键字(其实class在JavaScript中一直是保留字,目的就是考虑到可能在以后的新版本中会用到,现在终于派上用场了)。JS本身就是面向对象的,ES6中提供的类实际上只是JS原型模式的包装。现在提供原生的class支持后,对象的创建,继承更加直观了,并且父类方法的调用,实例化,静态方法和构造函数等概念都更加形象化。 //类的定义 class Animal { //ES6中新型构造器 constructor(name) { this.name = name; } //实例方法 sayName() { console.log('My name is '+this.name); } } //类的继承 class Programmer extends Animal { constructor(name) { //直接调用父类构造器进行初始化 super(name); } program() { console.log("I'm coding..."); } } //测试我们的类 var animal=new Animal('dummy'), wayou=new Programmer('wayou'); animal.sayName();//输出 ‘My name is dummy’ wayou.sayName();//输出 ‘My name is wayou’ wayou.program();//输出 ‘I'm coding...’
3.字符串模板 字符串模板相对简单易懂些。ES6中允许使用反引号 ` 来创建字符串,此种方法创建的字符串里面可以包含由美元符号加花括号包裹的变量${vraible}。如果你使用过像C#等后端强类型语言的话,对此功能应该不会陌生。
//产生一个随机数 var num=Math.random(); //将这个数字输出到console console.log(`your num is ${num}`);
4.解构: 自动解析数组或对象中的值。比如若一个函数要返回多个值,常规的做法是返回一个对象,将每个值做为这个对象的属性返回。但在ES6中,利用解构这一特性,可以直接返回一个数组,然后数组中的值会自动被解析到对应接收该值的变量中。 var [x,y]=getVal(),//函数返回值的解构 [name,,age]=['wayou','male','secrect'];//数组解构 function getVal() { return [ 1, 2 ]; } console.log('x:'+x+', y:'+y);//输出:x:1, y:2 console.log('name:'+name+', age:'+age);//输出: name:wayou, age:secrect
5.Promise: Promises是处理异步操作的一种模式,之前在很多三方库中有实现,比如jQuery的deferred 对象。当你发起一个异步请求,并绑定了.when(), .done()等事件处理程序时,其实就是在应用promise模式。 //创建promise var promise = new Promise(function(resolve, reject) { // 进行一些异步或耗时操作 if ( /*如果成功 */ ) { resolve("Stuff worked!"); } else { reject(Error("It broke")); } }); //绑定处理程序 promise.then(function(result) { //promise成功的话会执行这里 console.log(result); // "Stuff worked!" }, function(err) { //promise失败会执行这里 console.log(err); // Error: "It broke" });
26.promise的理解
ES6提供的解决异步处理方法
有两个优点
1.promise对象的状态不受外界影响
-pending 初始状态
-fulfilled 成功状态
-rejected 失败状态
2.promise的状态一旦改变,就不会再变,状态不可逆,只能由pending变成pending变成fulfilled或者由pending变成rejected
三个缺点
1.无法取消promise,一旦新建它就会立即执行,无法中途取消
2.如果不设置回调函数,promise内部抛出的错误,不会反映到外部
3.当处于pending状态时,无法得知目前进展到哪一个阶段
用法
const promise = new Promise(function(resolve, reject) { // ... some code if (/* 异步操作成功 */){ resolve(value); } else { reject(error); } });
27.同源策略
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。同源指的是协议,域名和端口号均相同则属于同源
28.前端跨域的方式
使用jsonp跨域,因为script标签引入的js是不受同源策略的限制,通过script标签引入一个js或者是一个其他后缀形式(如php,jsp等)的文件,此时文件返回一个JS函数的调用
通过cors跨域,实现cors通信的关键是服务器,只要服务器实现cors接口,就可以跨域
<script type="text/javascript"> var xhr = new XMLHttpRequest(); xhr.open("GET", "http://segmentfault.com/u/trigkit4/",true); xhr.send(); </script>
反向代理跨域,反向代理指的是在前端的服务器环境中, 短暂的开启一个后端服务器, 由后端服务器进行数据请求, 然后在将结果返回给前端