js高级小结

01基本对象

 
  1. var stu={

  2. name:'zsh',

  3. age:12,

  4. eat:function(){

  5. console.log(this);

  6. // 在基本对象内部this指的是当前的对象。

  7. console.log('吃了。。。。')

  8. }

  9. }

  10. stu.eat();

  11. var stu1={

  12. name:'ls',

  13. age:20

  14. }

02工厂方式创建对象

 
  1. var stu1=Student('zs',20);

  2. var stu2=Student('ls',13);

  3. var tea1=Teacher('aa',34);

03构造函数方式

 
  1. // 如果是构造函数,函数名一般大写。

  2. function Student(name,age){

  3. this.name=name;

  4. this.age=age;

  5. this.eat=function(){

  6. // 构造函数中的this指的是当前实例化对象

  7. console.log(this)

  8. }

  9. }

  10. // 实例化对象

  11. var stu=new Student('zs',20);

  12. var stu2=new Student('ls',18)

  13. stu2.eat();

04构造函数应用

 
  1. var flight=new Product('这是无人机',5999,['白色','渐变色','银色']);

  2. console.log(flight);

  3. // 直接通过id名可以选择标签

  4. title.innerHTML=flight.title;

  5. btn.onclick=function(){

  6. flight.buy();

  7. // 页面跳转

  8. location.href="03构造函数方式.html";

  9. }

  10. flight.buy();

05构造函数+原型方式

 
  1. function Product(title,price){

  2. this.title=title;

  3. this.price=price;

  4. // this.buy=function(){

  5. // counsole.log('hello')

  6. // }

  7. }

  8. var flight=new Product('无人机',4999);

  9. var mz=new Product('口红',399);

  10. // 存储的地址不一样。执行的功能一样。

  11. // 每次实例化对象的时候,都会生成一个buy方法。造成资源的浪费

  12. // console.log(flight.buy==mz.buy);

  13.  
  14. // 每一个构造函数,都有一个prototype属性/对象,该属性的所有方法和属性都能被构造函数继承。

  15. Product.prototype.buy=function(){

  16. console.log('购买了。。。。')

  17. }

  18. // 如果实例对象没有自己对应的方法,会去构造函数的prototype内部寻找。如果能找到,就会执行该方法。

  19. console.log(flight.buy==mz.buy);

  20. // 我们一般会把属性放置在构造函数内部,方法类的放在原型里面。这种方法封装的就称为构造函数+原型方式

06构造函数相关概念

 
  1. // this在普通位置一般指向的是window

  2. console.log(this);

  3. // 构造函数的首字母一般大写

  4. function Product(title,price){

  5. this.title=title;

  6. this.price=price;

  7. this.joinCar=function(){

  8. console.log(this.title);

  9. }

  10. }

  11. // 两个this指的都是实例化对象

  12. Product.prototype.buy=function(){

  13. console.log(this);

  14. console.log('购买了。。。。'+this.title);

  15. }

  16. var f=new Product('无人机',5999);

  17. f.buy();

  18. f.joinCar();

  19.  
  20. // 实例对象的__proto__指向构造函数的prototype

  21. console.log(f.__proto__==Product.prototype);

  22.  
  23. f.__proto__.buy=function(){

  24. console.log('您确认购买'+this.title);

  25. }

  26.  
  27. var m=new Product('口红',299);

  28. m.buy();

  29.  
  30. var arr=new Array(10,20,30);

  31.  
  32. // 可以通过constructor找到实例对象所属的构造函数

  33. console.log(arr.constructor==Array);

  34. console.log(m.constructor==Product);

  35.  
  36. // constructor在某些情况下没有那么靠谱,不好用

  37. // 官方推荐 使用 a instanceof b 判断a是否是b的实例对象

  38. console.log( arr instanceof Array)

07constructor

 
  1. function Product(title,price){

  2. this.title=title;

  3. this.price=price;

  4. this.joinCar=function(){

  5. console.log(this.title);

  6. }

  7. }

  8. // Product.prototype.buy=function(){

  9. // console.log(this);

  10. // console.log('购买了。。。。'+this.title);

  11. // }

  12.  
  13. // 相当于重写了Product.prototype 丢失了constructor属性

  14. Product.prototype={

  15. buy:function(){

  16. console.log('买');

  17. },

  18. joinCar:function(){

  19. console.log('加购物车');

  20. }

  21. }

  22. var p=new Product('口红',399);

  23. console.log(p.constructor);

  24. console.log(Product.prototype);

08构造函数使用场景

html代码

 
  1. <h3 id="title">标题</h3><br>

  2. 京东价<p id="price"></p><br>

  3. 选择颜色<p id="color"></p>

  4.  
  5. <script src="common.js"></script>

common.js代码

 
  1. // 创建函数 把对象封装起来

  2. function Student(name,age){

  3. return {

  4. name:name,

  5. age:age,

  6. eat:function(){

  7. console.log(this);

  8. // 在基本对象内部this指的是当前的对象。

  9. console.log('吃了。。。。')

  10. }

  11. }

  12. }

  13. function Teacher(name,age){

  14. return {

  15. name:name,

  16. age:age

  17. }

  18. }

  19. function Product(title,price,color){

  20. this.title=title;

  21. this.price=price;

  22. this.color=color;

  23.  
  24. }

  25.  
  26. Product.prototype.buy=function(){

  27. console.log('请问您需要购买'+this.title+'?');

  28. }

js代码

 
  1. var p=new Product('kouhong',2199,['粉色','白色']);

  2. title.innerHTML=p.title;

  3. price.innerHTML=p.price;

  4. for(var i in p.color){

  5. console.log(i);

  6. color.innerHTML+=p.color[i];

  7. }

09constructor

 
  1. function Product(name){

  2. this.name=name;

  3. }

  4. Product.prototype={

  5. // 重写以后丢失prototype属性,可以自己增加。

  6. constructor:Product,

  7. buy:function(){

  8. alert('您确定了')

  9. }

  10. }

  11. var p=new Product('手机')

  12. console.log(Product.prototype);

  13. console.log(p.constructor==Product);

10原型链

 
  1. // 原型链:当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或者方法,

  2. // 就会去关联的prorotype那里寻找,如果prototype没有。就会去prototype关联的prototype那里寻找。如果还没有,会一直向上寻找

  3. // 直到prototype....prototype..为null。从而形成了原型链(根本上来说就是继承)

  4. // a.isPrototypeOf(b) 判断a是否存在b的原型链中

  5. function Product(name){

  6. this.name=name;

  7. }

  8. console.log(Product.prototype.__proto__==Object.prototype);

  9. console.log(Object.prototype.__proto__);

  10. var p=new Product('手机');

  11. console.log(Product.prototype.isPrototypeOf(p));

  12. console.log(Object.prototype.isPrototypeOf(p));

  13. var person={

  14. name:'zs'

  15. }

  16. // 通过person创建对象student。类似于继承

  17. var student=Object.create(person);

  18. student.zid='101';

  19. var teacher=Object.create(student);

  20. teacher.zid='001';

  21.  
  22. // 自身不能说存在自身原型链中

  23. console.log(teacher.isPrototypeOf(teacher));

  24. console.log(student.isPrototypeOf(teacher));

  25. console.log(Object.prototype.isPrototypeOf(person));

  26. console.log(person.isPrototypeOf(teacher));

  27.  
  28. // 如果一个对象既有自有属性,又可以继承。自有属性为准

  29. // zid是teacher继承过来的

  30. console.log(teacher.zid);

  31. // a.hasOwnProperty(b)判断b属性是a自有的还是继承过来的

  32. console.log(teacher.hasOwnProperty('zid'));

11get和set

 
  1. var circle={

  2. r:20,

  3. // get获取值 get 变量名

  4. // set设置值 set 变量名

  5. get acr(){

  6. return Math.PI*this.r*this.r;

  7. },

  8. set acr(value){

  9. this.r=value;

  10. }

  11. }

  12. // 如果是赋值,自动调用set方法

  13. circle.acr=100;

  14.  
  15. // 如果是获取值,自动调用get方法

  16. console.log(circle.acr);

12属性特征

 
  1. var stu={

  2. name:'zs',

  3. age:12

  4. }

  5. // 正常赋值,属性可以直接修改

  6. stu.name='小明';

  7. // 属性可以被遍历出来

  8. // for (var i in stu){

  9. // console.log(i)

  10. // }

  11.  
  12. // 一般特殊情况才这样使用。

  13. // 设置属性的时候,可以配置属性特征

  14. Object.defineProperty(stu,'password',{

  15. value:123,

  16. // 是否可被修改

  17. writeable:false,

  18. // 是否可以被遍历

  19. enumerable:false,

  20. //是否可以被重新配置

  21. configurable:false

  22. })

  23. // 修改不成功,但是不会报错。writeable false

  24. stu.password=456;

  25. console.log(stu.password);

  26. // 不能被遍历 enumerable是false

  27. for (var i in stu){

  28. console.log(stu)

  29. }

  30.  
  31. // 不能被重新配置 configurable是false

  32. // Object.defineProperty(stu,'password',{

  33. // value:123,

  34. // // 是否可被修改

  35. // writeable:true,

  36. // // 是否可以被遍历

  37. // enumrable:true,

  38. // //是否可以被重新配置

  39. // configurable:true

  40. // })

13变量提升

 
  1. /变量声明

  2.  
  3. // 如果一个变量声明,会把声明提升到整个作用域的最前面,赋值还是在原来的位置

  4. // console.log(a);

  5. // var a=10;

  6. // 等价于

  7. // var a;

  8. // console.log(a);

  9. // a=10;

  10.  
  11.  
  12. // 如果变量没有声明,作用域是赋值以后的区域

  13. //报错a 没有声明在赋值之前没有办法直接使用

  14. // console.log(a)

  15. // a=10;

  16.  
  17. // 通过该方法定义函数,会把整个函数提升到作用域最前面。

  18. // add()

  19. // function add(){

  20. // console.log(111)

  21. // }

  22.  
  23.  
  24. // 如果通过该方法定义函数,只是把变量的定义提升到作用域最前面

  25. // 报错 add不是一个函数

  26. // add()

  27. // var add=function(){

  28. // console.log(111);

  29. // }

  30.  
  31.  
  32. // var a=10;

  33. // function add(){

  34. // // 变量提升,会把变量声明提升到整个作用域最前面

  35. // // js中只有函数的作用域,变量的作用域,是向上寻找距离其最近的开始的函数的{ 变量的作用范围就是该{以内。

  36. // // console.log(a);

  37. // // var a=100;

  38. // // 等价于

  39. // var a;

  40. // console.log(a);

  41. // a=100;

  42.  
  43. // }

  44. // add()

  45.  
  46.  
  47. // function add(){

  48. // var a=100;

  49. // }

  50. // add();

  51. // console.log(a); 报错 a的作用域是函数以内

  52.  
  53.  
  54. function add(){

  55. a=100;

  56. }

  57. // add(); 如果执行函数相当于给a赋值。a没有声明,作用域是赋值以后都可以使用

  58. // 如果不执行函数,相当于不会执行赋值语句.a会报错

  59. console.log(a);

14作用域和作用域链

作用域:在js中只有函数的作用域,在函数内部声明的变量,才能称为局部变量
                全局和局部只是相对来说
作用域链:在某个作用域内使用变量的时候,首先会在该作用域内寻找该变量,如果没有
                会一直向上寻找。这样的一种链式关系就是作用域链。其实指的就是变量的就近原则。

15原型链图

16this指向问题

this指向问题:
                    事件函数中:指向事件源
                    普通函数中:指向的是window对象
                    构造函数中:指向的是实例对象
                    普通对象中:指向的是当前对象

 
  1. btn.onclick=function(){

  2. console.log(this)

  3. }

  4. function Product(){

  5. this.buy=function(){

  6. console.log(this)

  7. }

  8. }

  9. var p=new Product();

  10. p.buy();

  11.  
  12. var stu={

  13. name:'zs',

  14. eat:function(){

  15. console.log(this)

  16. }

  17. }

  18. stu.eat();

  19. function add(){

  20. console.log(this)

  21. }

  22. add()

17call apply和bind

this指向问题:
                    普通函数中:指向的是window对象
                call apply和bind都可以用来修改this指向。只是使用方式不一样

 
  1. var stu={

  2. name:'zs',

  3. age:12,

  4. weight:200

  5. }

  6. function add(a,b){

  7. console.log(a,b,this.age)

  8. }

  9. // add(1,2);

  10.  
  11. // fn.call(所要指向的对象,参数1,参数2,...) 调用fn函数。修改this指向

  12. add.call(stu,1,3);

  13.  
  14. // fn.call(所要指向的对象,[参数1,参数2,...]) 调用fn函数。修改this指向

  15. add.apply(stu,[1,2]);

  16.  
  17. // bind不会直接调用函数 返回一个新的函数 修改了this指向

  18. var fn=add.bind(stu,1,2);

  19. fn();

18变量在内存中的存储

基本数据类型:在内存中以值的形式存在。 字符串、数值、布尔类型、null undefined

 复合数据类型:在内存中以地址的形式存在。 对象  

 
  1. var a=10;

  2. var b=a;

  3. a=100;

  4. console.log(b);

  5.  
  6.  
  7. var stu={

  8. name:'zs'

  9. }

  10.  
  11. // 传递的是地址

  12. var stu1=stu;

  13. stu.name='ls';

  14. console.log(stu1.name);

  15. </script>

19深拷贝与浅拷贝

浅拷贝:直接把对象的属性一一赋值,不考虑属性值类型,如果属性值为对象的时候,只要修改一个,其余对象对应数据都会改变

 
  1. var stu1={};

  2. stu1.name=stu.name;

  3. stu1.age=stu.age;

  4. stu1.hobby=stu.hobby;

  5. stu1.score=stu.score;

  6. stu.name='张三';

  7. stu.hobby[0]="弹吉他";

  8. console.log(stu1);

深拷贝:如果对象的属性值为基本数据类型,直接拷贝。如果对象属性对应的值对象,需要解析对象,再去拷贝

 
  1. var stu={

  2. name:'zs',

  3. age:14,

  4. hobby:['唱歌','跳舞'],

  5. score:{

  6. math:89,

  7. english:100,

  8. lizong:[100,100,200]

  9. }

  10. }

  11. var stu1={

  12.  
  13. }

  14. stu1.name=stu.name;

  15. stu1.age=stu.age;

  16. stu1.hobby=[];

  17. stu1.hobby[0]=stu.hobby[0];

  18. stu1.hobby[1]=stu.hobby[1];

  19. stu1.score={};

  20. stu1.score.math=stu.score.math;

  21. stu1.score.english=stu.score.english;

  22. var stu2={};

  23. // 快速实现深拷贝(函数递归调用)

  24. function deepCopy(a,b){

  25. for(var key in a){

  26. var i=a[key];

  27. if(i instanceof Array){

  28. b[key]={};

  29. deepCopy(i,b[key]);

  30. }else if(i instanceof Object){

  31. b[key]={};

  32. deepCopy(i,b[key]);

  33. }else{

  34. b[key]=i;

  35. }

  36. }

  37. }

  38. deepCopy(stu,stu2);

  39. console.log(stu2);

  40. // 只要调用deepCopy即可实现深拷贝

20高阶函数

 
  1. // 函数作为函数的实参。高阶函数

  2. function add(time,color){

  3. setTimeout(function(){

  4. color();

  5. },time)

  6. }

  7.  
  8. add(1000,function(){

  9. txt.style.color='red';

  10. })

  11.  
  12. add(2000,function(){

  13. txt.style.background='lime';

  14. })

  15.  
  16.  
  17. $('button').click(function(){})

21闭包

闭包:扩大了变量作用域

闭包:缩小变量作用域,防止变量污染

html:

 
  1. <button>按钮</button>

  2. <button>按钮</button>

  3. <button>按钮</button>

  4. <button>按钮</button>

  5. <button>按钮</button>

  6. <button>按钮</button>

js:

 
  1. var btns=document.getElementsByTagName('button');

  2. for(var i=0;i<btns.length;i++){

  3. // btns[i].onclick=function(){

  4. // // i全局变量,点击的时候i的值已经是btns.length;

  5. // tags[i].style.background='lime';

  6. // }

  7.  
  8. (function(b){

  9. btns[b].onclick=function(){

  10. // i全局变量,点击的时候i的值已经是btns.length;

  11. btns[b].style.background='lime';

  12. }

  13. })(i);

  14. }

  15.  
  16. //计数器

  17. // 1、可以在函数的外部访问到函数内部的局部变量

  18. // 2、让这些变量始终保存在内存中,不会随着函数的结束而自动销毁

  19. var add=(function(){

  20. var count=0;

  21. return function(){

  22. return count+=1;

  23. }

  24. })()

  25. console.log(add);

  26. console.log(add());

  27. console.log(add());

  28. console.log(add());

  29. console.log(add());

自调用函数 ;( function(){})(); 前后都需要有结尾;

 
  1. (function(){

  2. // 放置的是一段有特殊功能的代码

  3. var m=10;

  4. })();

  5.  
  6. console.log(m)

猜你喜欢

转载自blog.csdn.net/aa67567456/article/details/112993376
今日推荐