this指向
this属于js的一个关键字
谁调用this,this就指向谁
1.对象中的调用方式
得到结果11111 kerwin
2.this指向window窗口
因为function是window调用的
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)
})
改变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.合并对象
使用场景:注册页面后,修改个人信息
(如果有同名的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{}导出(想让谁暴露就让谁暴露)
这样a-common就不能被随意调用了
module import导入
首先必须给script标签加一个type=“module”猫叫的属性
然后在script里写
import{需要调用的,并用逗号连接}from 单引号./文件 单引号
重名解决
如果导入的时候遇到重名现象的话,只需在导入里给它重命名就可以了,原名和现名用 as
连接
依赖不乱
在用之前,import导入
这样在引入的时候,就无所谓顺序了
default默认导出
这时候导入的时候就不限制写{导入的东西}了,随便写
——————————————————————————————————
在我们学习ES6 class之前,我们首先需要对面向对象进行了解,所以我们先来讲一下“面向对象”
————————————————————————————————————
面向对象
工厂效果
//工厂函数
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增加一次内存)
需补充修改:
那个title,list现在是分开写,当然你也可以直接写成data1,把整个传上去,不过这时候,你this那里就需要写成data.title了
obj1.render() = function(){获取你的内容}
效果(在function里调用,渲染页面的作 用)
最后的时候记得function外记得再调用渲染obj1.render()
最后再写....innerHTML=this....
.join("")
让他们合起来成字符串
prototype 原型(共用一个内存)
把上面 function中this.render剪切掉,在下面调用
对象自带属性——双下划线_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
}
}