JS学习之—this,ES6,面向对象思想(118~135)

99 阅读7分钟

this指向

this属于js的一个关键字

谁调用this,this就指向谁

1.对象中的调用方式

image.png 得到结果11111 kerwin

2.this指向window窗口

因为function是window调用的 image.png

3.dom事件绑定中的this(指向节点)

dom0写法

 <div id="box">click</div>
    <script>
       box.onclick = function(){
        console.log(this)
       }
    </script>

dom2写法

(虽然这个形式很像是window调用的,但是这个跟dom0效果一样,是对象box这个节点调用,只是写法差异)

 box.addEventListener("click",function(){
        console.log("11111",this)
      })

image.png

改变this指向:call,apply,bind

原来是

 var obj1={
        name:"obj1",//每条后面记得加逗号
        getName:function(){
            console.log("getName",this.name)
        }
    }

    var obj2={
        name:"obj2",
        getName:function(){
            console.log("getName2",this.name)
        }
    }


    obj1.getName()
    obj2.getName()

改变 我现在想让原obj1的this去指向obj2

区别: (从call/apply那个语句传到function的形参里了)

call可以传多个参数

但是apply传后面的参的话,必须用数组的形式(只支持两个参数,第二个参数为数组)

call apply

    //强行改变this的指向
    //执行前面函数,并改变this执行为函数的第一个参数
    //括号里的obj2是这个的参数
    obj1.getName.call(obj2)
    obj1.getName.apply(obj2)

bind

 var fun1=obj1.getName.bind(obj2)
 console.log(fun1)
 fun1()//手动执行
/ 改变this指向为函数的第一个参数,但不会自动执行函数
//它会给你返回一个新的函数,不过这个新函数的this指向已经被你掰成obj2了

ES6

定义变量(let变 const常)

let与var区别:

1. let不能先调用后定义

2.不能重名,重名不会覆盖定义,会直接报错

3.块级作用域: var定义局部变量,在局部的外部依然可以用

let只能存活于你这个局部(也就是你这个大括号块级里)的里面

let与const的区别:

1. let是定义变量的,const是定义常量的

2. let可以改变原来赋的值,但是const常量不能重新赋值

 let name="kerwin"
    name="xiaoming"

TIP:这里需要注意的是,你如果想让常量重新赋值,可以这样

(原理是只要保证你obj的值不被覆盖就可以)(简单类型和复杂类型在的堆栈不同)

  const obj={
    name:"kerwin"
  }
  //这样可以(相当于还是用之前的钥匙打开进去改了一下)
  obj.name="xiaoming"
  //这样不行(对obj覆盖了,相对于直接换了个钥匙)
  obj={name:"xiaoming"}
  console.log(obj)

ES6的箭头函数

function(){}————————()=>

1. 当形参只有一个时,可以省略形参,也就是把小括号去掉,只留里面的参数然后=>

2. 当你函数里语句只有一个或者只有返回值时,可以省略大花括号{},直接写在=>后面

如果你你这个返回值本身是个对象的话,省略完需要在对象外面加个()括号,不然会被当成没有省略前的花括号

3. 箭头函数没有arguments

arguments是函数内建特殊变量,可以在没有形参的情况下,拿到所有实参(伪数组)

TIP:回顾(怎么把伪数组强行转成真数组): console.log(Array.from(arguments))

4. 箭头函数的this是父级作用域的,自己本身里没有(所以箭头函数里如果有指向window的,会变成指向父级的)

ES6的解构赋值

快速地从对象和数组中获取里面的成员

比如可以让两个数交换(要用var定义)...

数组

  var arr=["xiaoming","tiechui","kerwin"]
  //原来这样拿arr[0]
  
 //拿哪个写哪个
    let [x,y,z]=arr
    console.log(x,y,z)

对象

原来必须写成这样 document.write(obj.name)obj.什么

但是用解构的话可以这样写↓

 var obj={
        name:"kerwin",
        age:100,
        location0:"dalian"
    }

    let {name,age,location0}= obj
    document.write(name)
    document.write(age)
    document.write(location0)

ES6的对象简写(很方便)

如果前面的key值和后面的变量一样,那就可以省略成一个

ES6展开运算符 ...

数组展开方面

1.合并数组
    var a=[1,2]
    var b=[3,4]
    //console.log(a,concat(b))
    //原来这种打印出来是一个大数组里有a、b两个数组
    //但是现在这种做法可以让两个小数组展开,只有一个大数组
    var c=[...a,...b]
    console.log(c)
2.复制(且不改变原值)
    var a=[1,2]
    var b=[...a]
    //原来是这样做的
    //var b=a.slice()
    //var b=a.concat()
    b[0]="kerwin"

    console.log(a,b)
3.拿参数:实参,形参

tip:三个点的参数必须是形参的最后一个

在实参里写,可以直接对号入座

4.找最值
  var arr=[1,2,3,4,5,6,7,8]
  var res=Math.max(...arr)
  console.log(res)
5.伪数组转换
 function test(){
    //var arr=Array.from(arguments)
    var arr=[...arguments]
    console.log(arr)
  }
  test(1,2,3,4,5)

对象展开方面

1.合并对象

使用场景:注册页面后,修改个人信息

image.png

(如果有同名的key,会被覆盖

var obj1={
    name:"kerwin",
    age:100
}
var obj2={
    location:"dalian"
}
var obj={
    ...obj1,
    ...obj2
}
console.log(obj)

ES6模块化语法(必须加type="module")

必须在live serve服务器环境下运行,view in browse中不行

特点:私密不漏;重名不怕;依赖不乱

写法:

私密不漏 ↓

export{}导出(想让谁暴露就让谁暴露)

image.png 这样a-common就不能被随意调用了

module import导入

首先必须给script标签加一个type=“module”猫叫的属性

然后在script里写

import{需要调用的,并用逗号连接}from 单引号./文件 单引号

重名解决

如果导入的时候遇到重名现象的话,只需在导入里给它重命名就可以了,原名和现名用 as 连接

依赖不乱

在用之前,import导入

联想截图_20231112191536.png 这样在引入的时候,就无所谓顺序了 image.png

default默认导出

image.png 这时候导入的时候就不限制写{导入的东西}了,随便写

image.png —————————————————————————————————— 在我们学习ES6 class之前,我们首先需要对面向对象进行了解,所以我们先来讲一下“面向对象” ————————————————————————————————————

面向对象

image.png

工厂效果

 //工厂函数
    function createObj(name){
        var obj={}
        obj.name=name,
        obj.material=[]
        return obj
    }
    var obj1=createObj("蒸羊羔")
    console.log(obj1)

    var obj2=createObj("烧花鸭")
    console.log(obj2)

自定义构造函数

也有工厂效果(更建议用这个自定义的方法)

  //在下面调用的时候,前面加上new,加上后会自动创建对象
    function createObj(name){
      this.name=name
      this.material=[]
      this.cook=function(){

      }
      //自动返回对象
    }
    var obj1=new createObj("蒸羊羔")
    console.log(obj1)

需要注意的问题

1.创建对象时,首字母大写

2.构造函数不写return返回

3.构造函数中this指向:p129

面向对象的原型

之前以一个来举例(一个new增加一次内存)

image.png image.png 需补充修改: image.png 那个title,list现在是分开写,当然你也可以直接写成data1,把整个传上去,不过这时候,你this那里就需要写成data.title了


联想截图_20231112204827.png

联想截图_20231112204907.png obj1.render() = function(){获取你的内容} 效果(在function里调用,渲染页面的作 用)

最后的时候记得function外记得再调用渲染obj1.render()

最后再写....innerHTML=this....

.join("")让他们合起来成字符串

image.png

prototype 原型(共用一个内存)

把上面 function中this.render剪切掉,在下面调用

联想截图_20231113211712.png

对象自带属性——双下划线_proto_===构造函数的原型.prototype

扩展:obj1.toString()原型链概念p130

.ES6续

ES6的class

  class CreateObj{
      //构造器函数
      constructor(name){
        this.name=name
      }
       
      say(){
          console.log(this.name,"hello")
        }
    }


    var obj=new CreateObj("kerwin")
    console.log(obj)


//原型_______________________________________
    /*CreateObj.prototype.say=function(){
      console.log(this.name,"hello")
    }*/
    obj.say()

面向对象继承

分为
构造函数继承
原型继承
组合继承

1.构造函数继承call——继承“属性”

需要被继承的类名.call(this,继承元素,继承元素)

需要被继承的类名.apply(this,[继承元素,继承元素])

2.原型继承——继承原型上的方法

person>student(just随便命名)

这种不可以,会互相影响

Student.prototype= Person.prototype

应该new一下

(新的)Student.prototype= new Person()

可以基础增加,可以覆盖,可以增强方法

(新的)Student.prototype.方法=function(){}

ES6继承

1.extends原型继承(继承父类的原型)

 //父类
    class Person{
      constructor(name,age){

        this.name=name
        this.age=age

      }
      say(){
        console.log(this.name,"hello")
      }
    }
    //子类
    //这个extends会继承上面的原型方法say
    class Students extends Person{}

    var obj=new Student()
    console.log(obj)

2.super属性继承

super必须写在构造器的最上面,也就是super上面不能有代码,属于构造器中的第一个代码

如果想继承属性,就在这个子类里面写构造器,再用super继承

 class Students extends Person{
      constructor(name,age,grade){
        super(name,age)//Person.call(this,name,age)
        this.grade=grade
      }
    }