闭包
一个函数a的返回值是子函数b,函数b使用了a函数里面的局部变量,在外部调用了子函数b,本来该销毁的函数a,因为函数b使用了a函数的局部变量,这个变量无法销毁,并存放到了一个新的空间,这个空间被称为闭包。
function a(){
var a=1;
return function b(){
console.log(a);
}
}
let r=a();
IIFE
IIFE(立即执行函数)常用的几种方式:
立即调用函数表达式 var f = function(){}; function g(){};
IIFE表示定义函数时,直接调用。 ;(function f(a){ return 123; })(1) ;(function f(){}()) ;+function f(){}() ;-function f(){}() ;!function f(){}()
对 “对象” “构造器” “属性”的理解
对象
对象实际上就是类的具体的事物,也就是具体的对象,是真实存在的
- 由类(函数)创建的;
- 一切皆对象;
- 对象是属性的无序集合;
构造器
构造器实际上就是我们类的另一种说法,我们创造对象是通过new 后面加上构造器创造的
一般情况下,如果你函数的首字母大写了,那么后期通常将他作为一个构造器(类)去使用
在js中有很多类可以创建对象,这些类也叫作构造器
Number类
String类
Boolean类
Object类
Array类
Date类
属性
属性名:属性值 这一整条 叫属性
属性是对该类事物的描述,方法则是该类事物能做的事情
属性指的是与对象相关的值;
属性通常可以增删查改,但某些属性是只读的。
判断数据类型的方式
-
typeof
-
instanceof
-
constructor
-
toString
let obj={name:"wc"}; console.log(obj.toString());//[object Object] let arr=[1,2,3]; console.log(arr.toString());//1,2,3 console.log(typeof arr.toString());//1,2,3
更多操作数组打点调用toString 和 对象打点调用toString结果是不一样的
数组的结果还是和数组元素一模一样的字符串 对象的结果是[object Object]
-
Object.prototype.toString()
想借用Object原型对象上的toString 那么肯定需要去使用call
console.log(Object.prototype.toString.call(a));//[object Array] console.log(Object.prototype.toString.call("hello"));//[object String] console.log(Object.prototype.toString.call(123));//[object Number] console.log(Object.prototype.toString.call(true));//[object Boolean] console.log(Object.prototype.toString.call(fn));//[object Function] console.log(Object.prototype.toString.call(date));//[object Date] console.log(Object.prototype.toString.call(b));//[object Undefined] console.log(Object.prototype.toString.call(null));//[object Null]
-
判断是不是数组:isArray
call,apply,bind的区别
call:本意是 打电话
<script>
var name="qq";
function say(){
console.log("我是say函数");
console.log(this.name);
}
let obj1={name:"wc"};
let obj2={name:"xq"};
// 我现在 想借用window上面的say方法 输出我这两个对象的名字
say.call();
// say函数目前有四个角色 1.普通函数 2.方法 3.对象 4.类
// 如果一个函数后面.call() 会让函数执行
// 但是如果不写参数 就是普通的让函数执行 没有其他意思
say.call(obj1);
say.call(obj2);
// 以上表示 obj1和obj2借用了say函数
// 当call的参数只有一个对象的时候 那么表示这个对象借用call前面的函数
// 那么这里面都做了什么? 1.让函数执行 2.改变了this的指向,让this指向参数的对象
function f1(a,b){
console.log("我是"+this.name+"的函数,传进来的参数是"+a+","+b);
}
f1(1,2)
//既想用call去借用f1 又想传参
f1.call(obj1,1,2)
f1.call(obj2,3,4)
</script>
apply:本意的 应用 申请 的意思
<script>
function f1(a,b){
console.log("我是"+this.name+"的函数,传进来的参数是"+a+","+b);
}
let obj1={name:"wc"};
let obj2={name:"xq"};
// apply的使用
f1.apply(obj1,[1,2])
f1.apply(obj2,[3,4])
</script>
bind:本意 绑定 的意思
<script>
function f1(){
console.log("我是"+this.name+"的函数,传进来的参数是");
}
let obj1={name:"wc"};
let obj2={name:"xq"};
// bind的使用
f1.bind(obj1)();
f1.bind(obj2);
// bind的返回值是一个改变过this指向的函数
// 以上面这个为例 那么f1.bind(obj1)的返回值就是一个改变了this指向 让this指向obj1的f1函数
</script>
call aplly:
都可以发变一个函数中的this指向,并且让函数执行。
call 和aplly的区别是:传参方式的不同
bind:
也可以改变函数中this的指向,但是不会让函数执行,仅仅是改变this指向。返回一个改变了this指向的函数
继承的几种方式及特点
-
原型继承
实际上就是把父级的私有属性和公有属性 都继承为子级的公有属性;
核心就是通过改变子级的原型对象 让子级的原型对象变成父级的实例化对象;
父级的私有属性都给了实例化对象 而把实例化对象作为子级的原型对象 那么这些属性就全部变成了子级的公有属性.
特点:
1)继承父类的公有属性和私有属性 作为子类的公有属性
2)核心代码:Son.prototype = new Father();<script> function Father(){ this.a=100 // 如果说把Father当作一个构造器的话 那么a就是他的私有属性 } Father.prototype.getA=function(){ console.log(this.a); // 如果把方法或者属性写到了自己所对应的原型对象上 那么这个属性或者方法就是公有的 // 为什么是公有 因为每一个用Father生成的对象 都可以沿着__proto__找到这个原型对象然后用 } function Son(){ } Son.prototype=new Father(); Son.prototype.constuctor=Son; let son=new Son(); console.log(son.a); son.getA() </script>
-
call继承
call的作用:1.改变this的指向 2.执行函数
特点:
1)继承父类的私有属性 作为子类的私有属性 用的不一般情况下,别人私有的,是不想让别人继承
2)Father.call(this);<script> function Father(){ this.a=110; } Father.prototype.getA=function(){ console.log(this.a); } function Son(){ // 如果想用call继承 // 那么需要在子级里面写一个东西 Father.call(this); // Father的角色 1.函数 2.也是一个类 3.还是一个对象 } let son=new Son(); // new作用有哪些? // 1.开了一个新空间让this指向这个空间 // 2.返回一个地址 // 3.执行构造器函数 console.log(son.a);//110 son.getA()//报错
3.组合继承
特点:
1)继承父类的公有属性和私有属性 作为子类的公有属性 原型继承
2)继承父类的私有属性 作为子类的私有属性 call继承
3)父的私有属性被继承了两次,当我们去访问一个属性时,会先访问私有属性
<script>
function Father(){
this.a=110;
}
Father.prototype.getA=function(){
console.log(this.a);
}
function Son(){
Father.call(this)
}
Son.prototype=new Father();
Son.prototype.constructor=Son;
let son=new Son();
console.log(son.a);
son.getA();
</script>
this的几种情况
1.this出现在普通函数中的时候 this代表的是window
function fn(){
console.log(this);
}
2.this如果出现在事件中 那么this指的就是事件源
let btn=document.getElementById("btn");
btn.onclick=function(){
console.log(this);
}
3.对象中方法里面的this 指的是调用这个方法的对象
let obj={
name:"wangcai",
age:"15",
// 在对象中定义方法
run:function(){
console.log(this);
console.log("run...");