1、什么是构造函数?
通过new函数名来实例化对象的函数叫构造函数,任何的函数都可以作为构造函数存在。之所以有构造函数与普通函数之分,主要从功能上进行区别的,构造函数的主要功能为初始化对象,特点是和new 一起使用。new就是在创建对象,从无到有,构造函数就是在为初始化的对象添加属性和方法。构造函数定义时首字母大写。当构造函数中有返回对象时候,最终new出来的对象会是构造函数的返回值,而不是new过程中生成的对象。仅当构造函数返回值是对象时有效,当不是对象时依旧返回new过程中形成的对象
2、创建对象的方式有哪些?举例说明
1、new 操作符 + Object 创建对象
1 <script>
2 var person = new Object() ;
3 person.name = ‘zs‘ ;
4 person.age = 12 ;
5 person.sayHi = function(){
6 return ‘姓名‘+this.name+‘年龄‘+this.age ;
7 }
8 console.log(person.sayHi()) ;
9 </script>
2、字面量创建对象
1 <script>
2 var person = {
3 name:‘zs‘,
4 age:12,
5 sayHi:function(){
6 return this.name + this.age ;
7 }
8 }
9 console.log(person.sayHi()) ;
10 </script>
3、工厂模式创建
1 <script>
2 function createPerson(name , age) {
3 var o = new Object() ;
4 o.name = name ;
5 o.age = age ;
6 o.sayHi = function(){
7 return this.name + this.age ;
8 }
9 return o ;
10 }
11 var per = createPerson(‘zs‘ , 12) ;
12 console.log(per.sayHi()) ;
13 </script>
4、构造函数模式
1 <script>
2 function Person (name , age ) {
3 this.name = name ;
4 this.age = age ;
5 this.sayHi = function(){
6 return this.name + this.age ;
7 }
8 }
9 var per = new Person(‘zs‘,12) ;
10 var per1 = new Person(‘lisi‘,36) ;
11 console.log(per.sayHi()) ;
12 console.log(per1.sayHi()) ;
13 </script>
5、原型模式
1 <script>
2 function Person(hobbies) {
3 this.hobbies = hobbies ;
4 }
5 Person.prototype.name = ‘zs‘ ;
6 Person.prototype.age = 18 ;
7 Person.prototype.sayHi = function(){
8 return this.age + this.name ;
9 }
10 console.log(Person.prototype) ;
11 var per = new Person() ;
12 per.hobbies = ‘篮球‘ ;
13 console.log(per.hobbies) ;
14 console.log(per.name) ;
15 </script>
3、js 中实现继承的方式
1、call方式实现继承
1 <script>
2 // 解决方案:继承的时候不用改变原型的指向,直接调用父及构造函数给属性赋值
3 // 借用构造函数:call() 构造函数.call(当前对象,属性1,属性2,...)
4 // 解决了属性的继承,方法不能继承
5
6 function Person(name,age,sex,weight){
7 this.name = name ;
8 this.age = age ;
9 this.sex = sex ;
10 this.weight = weight ;
11 }
12
13 Person.prototype.sayHi = function(){
14 console.log("你好")
15 }
16
17 // 学生的构造函数
18 function Student(name,age,sex,weight,score){
19 // 借用构造函数实现继承
20 // call改变this的指向,当前指向Person,不指向Student,谁调用this就指向谁
21 Person.call(this,name,age,sex,weight)
22 this.score = score ;
23 }
24 Student.prototype.test = function(){
25 console.log("考试")
26 }
27 // 实例化
28 var stu = new Student("zs",12,‘nan‘,40,100)
29 console.log(stu.name,stu.age,stu.sex,stu.weight,stu.score)
30 stu.test() ;
31 // stu.sayHi() ;//报错
32 </script>
2、组合继承的方式实现继承
1 <script>
2 // 通过原型继承 --- 属性问题
3 // 通过构造函数---- 方法问题
4 // 组合继承: 原型中的继承 + 借用构造函数中的继承
5
6 function Person(name ,age ,sex){
7 this.name = name ;
8 this.age = age ;
9 this.sex = sex ;
10 }
11 Person.prototype.sayHi = function(){
12 console.log("你好")
13 }
14
15 // 构造函数实现学生的类
16 function Student(name,age,sex,score){
17 // 借用构造函数解决属性值重复的问题
18 Person.call(this,name,age,sex)
19 this.score = score ;
20 }
21 // 通过改变原型指向,继承方法
22 Student.prototype = new Person() // 不传值---属性已经通过构造函数解决了
23 Student.prototype.study = function(){
24 console.log("学习")
25 }
26
27 // 创建实例对象
28 var stu = new Student("zs",12,‘man‘,100)
29 console.dir(stu)
30 stu.sayHi()
31 console.log(stu.name)
32 // 通过组合继承的方式,属性和方法都被继承了
33 </script>
4、什么是闭包?有什么作用?
1、闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
2、闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。
5、什么是预解析?
1、预解析:在当前作用域下,js运行之前,会把带有var和function关键字的事先声明,并在内存中安排好,然后再从上到下执行js语句,预解析只会发生在通过var定义的变量和function上。
2、只要是通过var定义的,不管是变量,还是函数,都是先赋值undefined,如果是变量,也不管变量有没有赋值,在预解析阶段,都是会被赋值为undefined。
3、函数在预解释的时候,它把它分解成两部分来对待,第一部分是fn函数,而第二部分是(),一个匿名函数,执行时会报错。如果小括号带参数,虽然不会报错,会打印出来,但并不能把fn执行,也不能当成参数传递给fn函数。
4、预解析是发生在当前作用域下的,不会在同一个变量上重复的发生,也就是一个变量如果已经在当前作用域下预解析了,不会再重复解析。
5、预解析的过程:
第一步,会预先根据关键字var、function等,来查找一些需要被解析的东西。
第二步,给这些需要被解析的东西提前赋值,所有的变量,提前赋值:undefined;所有的函数,在正式运行代码前,都赋值为整个函数块。
第三步,“预解析”结束后,浏览器再逐行解读代码,并通过表达式:= + - * – ++ !等来修改这些“预解析”的值。
原文:https://www.cnblogs.com/gaobz/p/14434692.html