JavaScript高级知识点

一、三种创建对象的方法

1.字面量

 let obj1={
     name:'zs',
     age:20,
     sex:'male',
     eat:function () {
         console.log(name+'在吃东西');
     }
 }

2.调用系统构造函数

let obj2=new Object();
  obj2.name='ls';
  obj2.age=18;
 obj2.sleep=function(){
     console.log('在睡觉');
  }

3.自定义构造函数

1.构造函数中的this就是实例对象
2.原型对象的方法中的this也是实例对象
 function Person(name,age) {
     this.name=name;
     this.age=age;
     this.play=function () {
         console.log('他在玩游戏')
     }
 }
 //实例化一个对象,并对他的属性进行初始化
 let woman=new Person('wang',55);
1.开辟空间存储对象;
2.把this设置为当前实例对象;
3.设置属性和方法的值;
4.把this对象返回。

4.工厂模式创建对象

通过创建函数的方式创建对象

 function createObject(name,age) {
       let obj=new Object();
       obj.name='ls';
       obj.age=18;
       obj.sayHi=function(){
           console.log('打招呼');
       }
       return obj;
   }
   let obj3=createObject('ww',4);

二、原型

__proto__:是浏览器使用的原型对象,在实例中存在
prototype:是程序员使用的原型对象,在构造函数中存在

1.判断实例对象是不是某个数据类型的对象的两种方法

dog是实例对象,判断dog是不是animal类型的,就判断它的构造器是不是指向animal

console.log(dog.__proto__.constructor==Animal);//方法一,也可以省略__proto__
console.log(dog instanceof Animal);//方法二,这种方式更准确,推荐使用,因为实例对象的原型也有可能指向Object

2.原型方法相互调用

在这里插入图片描述

3.原型的指向问题

 1.构造函数和实例对象都指向原型对象;
 2.原型对象中的构造器指向该原型对象的构造函数;
 3.实例对象可以直接访问原型对象中的属性和方法;
 4.构造函数中的prototype中的__proto__指向的是Objec中的prototype,prototype中有__proto__,最终指向null;
 5.实例对象与原型对象间是通过__proto__来联系的,这个关系叫做原型链。
console.log('per.__proto__ == Person.prototype');//true

在这里插入图片描述

4.原型的指向可以改变

1.实例对象的__proto__指向的是该对象所在构造函数的原型对象;
2.构造函数的prototype的指向改变了,实例对象中__proto__的指向也会相应改变。
 //人的构造函数
 function Person(age) {
       this.age=age
  }
  //人的原型方法
  Person.prototype.sayHi=function () {
       console.log('人打招呼');
  };
  //学生的构造函数
  function Student() {}
  //学生的构造方法
  Student.prototype.eat=function () {
       console.log('学生吃饭')
  };
  //学生的原型指向人的构造函数
  Student.prototype=new Person(10);
  //创建学生的实例对象
  let stu=new Student();
  stu.sayHi();//stu只能调用人的原型方法
  //stu.eat();报错,因为原型的指向改变了

在这里插入图片描述

原型指向改变如何添加原型方法

在指向改变之后再添加原型方法
   function Person(age) {
        this.age=age
   }
   Person.prototype.sayHi=function () {
        console.log('人打招呼');
   };
   function Student() { }
   Student.prototype=new Person(10);//指向改变
   Student.prototype.eat=function () {//再添加原型方法
       console.log('学生吃饭')
   };
   let stu=new Student();
   stu.sayHi();
   stu.eat();//这里的eat就可以正常调用

5.原型的作用

数据共享,节省内存空间
function Person(name,age) {
     this.name=name;
     this.age=age;
 }
 Person.prototype.sex='男';//原型中的属性
 Person.prototype.play=function () {//原型中的方法
     console.log('他在玩游戏')
 };
let obj4=new Person('小红',5);
let obj5=new Person('小黑',8);
console.log(obj4.play == obj5.play);//true,指向同一个函数,节省了内容空间

实例对象中的属性与原型对象中的属性重名

1.先在实例函数中找,找不到在去prototype中找。
 function Person(age,name) {
      this.age=age
     this.name=name;
 }
 Person.prototype.age=18;
 let per = new Person(15,'张三');
 console.log(per.age);//15
2.通过实例对象能否改变原型对象的属性?不能
per.age=14;  //只能改变实例对象中的属性
 function Person(age,name) {
 	 this.age=age;
     this.name=name;
 }
    per.prototype.age=20;//改变了原型对象的属性
    console.log(per.age);//20
    

三、函数的自调用

一次性函数:函数声明的同时,进行函数调用
(function(win){
	var num=0;//局部变量
	//js是一门动态语言,对象没有这个属性,点了就有了
	win.num=num;//把局部变量变成全局变量
})(window);
	console.log(num);//报错,没有定义与赋值

四、面向对象的特征

1、封装

1.一个值存在一个变量中;
2.重复的代码放在一个函数中;
3.一系列属性放在一个对象中;
4.一些功能相似的函数(方法)放在一个对象中;
5.一些相似的对象放在一个js文件中。

2、多态

每个对象使用某个行为时会产生不同的结果。
想有多态就要先有继承,js中可以模拟多态,但不会去模拟,因为会导致数据不能共享。

3、继承

孩子继承父亲的属性和方法,同时又可以新增自己的属性和方法,继承是为了减少代码冗余

是一种关系,类与类之间的关系。
但js中没有类的概念,于是采用了构造函数来模拟类,通过原型实现继承。

①原型继承

通过改变原型的指向实现继承

   function Person(name,age) {
        this.name=name;
        this.age=age;
    }
    Person.prototype.eat=function () {
        console.log("吃饭");
    };
    Student.prototype =new Person('小刘',18);
    function Student(score) {
        this.score=score;
    }
    Student.prototype.play=function () {
        console.log("学生们在玩耍");
    }
    let stu =new Student(100);
    //继承过来的
    console.log(stu.name);
    console.log(stu.age);
    stu.eat();
    //学生自己的
    console.log(stu.score);
    stu.play();
原型的作用一:数据共享节省内存空间
原型的作用二:实现继承

出现问题:原型实现的继承,如果使用多个实例,则他们的名字和年龄是相同的

②借用构造函数继承

    function Person(name,age) {
        this.name=name;
        this.age=age;
    }
    Person.prototype.eat=function () {
        console.log("吃饭");
    };

    function Student(name,age,score) {
        Person.call(this,name,age,);
        this.score=score;
    }
    Student.prototype.play=function () {
        console.log("学生们在玩耍");
    };
    let stu1 =new Student("小刘",18,100);
    console.log(stu1.name,stu1.age,stu1.score);
    let stu2 =new Student("小魏",3,101);
    console.log(stu2.name,stu2.age,stu2.score);

出现问题:借用构造函数实现的继承,不能继承父亲的方法

③组合继承

组合继承通过结合原型继承和借用构造函数继承的方式,解决了两者的不足
    function Person(name,age) {
        this.name=name;
        this.age=age;
    }
    Person.prototype.eat=function () {
        console.log("吃饭");
    };

    function Student(name,age,score) {
        Person.call(this,name,age);//借用构造函数继承,只继承属性
        this.score=score;
    }
    Student.prototype=new Person();//原型继承,因没有传值,这里就只继承方法
    Student.prototype.play=function () {
        console.log("学生们在玩耍");
    };
    let stu1 =new Student("小刘",18,100);
    console.log(stu1.name,stu1.age,stu1.score);
    let stu2 =new Student("小魏",3,101);
    console.log(stu2.name,stu2.age,stu2.score);
    stu1.play();
    stu1.eat();

④拷贝继承

直接把某个对象赋值给另一个对象,也是拷贝赋值 (let obj1=obj2;),
但这样仅仅是改变了地址的指向,在堆里没有自己的空间。
       function Person() {}
    Person.prototype.name='小刘';
    Person.prototype.age=18;
    Person.prototype.eat=function () {
        console.log("吃饭");
    };
    let obj={};
    for (let key in Person.prototype){
        obj[key]=Person.prototype[key];
    }
    console.log(obj.name,obj.age);
    obj.eat();

五、闭包

闭包就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,
因此可以把闭包简单理解成"定义在一个函数内部的函数"。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>闭包</title>
    </head>
    <body>
        <div>a</div>
        <div>b</div>
        <div>c</div>
        <div>d</div>
        <script type="text/javascript">
            var divs=document.getElementsByTagName("div");
            for (var i=0;i<divs.length;i++) {
                divs[i].onclick=function(){
                    alert(i);
                }
            }
        </script>
    </body>
</html>

六、this的指向

1.普通函数中的this

window:BOM 中顶级对象是 window,浏览器中所有定西都是 window 的

2.对象.方法中的this

实例对象
    function Student() {
        console.log(this);
        this.sayHi=function () {
            console.log(this);//实例对象
        }
    }
    let stu = new Student();
    console.log(stu);

3.定时器中的this

window:window 调用的方法可以省略 window
 window.setInterval(function () {
     console.log(this)
 },1000);

4.构造函数中的this

实例对象
   function Student() {
        console.log(this);
    }
    let stu = new Student();
    console.log(stu);

5.原型对象方法中的this

实例对象
    function Student() {
        console.log(this);
    }
    Person.prototype.sleep=function(){
        console.log(this);
    };
    let stu = new Student();
    console.log(stu);

七、严格模式

必须通过对象调用方法
 "use strict";
 function f1() {
	console.log(this);//window
}
 window.f1();

八、综合知识

1、数组可以存储任何类型的数据

2、回调函数:把函数当参数使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值