06—js函数(构造函数,原型,原型链。。。。。。)

一、初识函数

函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。

通过函数可以封装任意多条语句,而且可以在任何地方,任何时间进行调用和执行

二、创建函数

(1)function命令, 使用关键词 function来声明函数

注:关键词 function 必须是小写的,并且必须以与函数名称相同的大小写来调用函数。

  • 被提前

变量的声明被提前:使用var关键字声明的变量,会在所有的代码执行之前被声明但不会赋值

函数的声明被提前,使用function声明的函数,会在所有的代码执行之前就被创建

(2)函数表达式, 使用变量初始化函数(字面量方式定义函数)

 

  1. 注意:以表达式定义的函数并没有“被提前”。
  2. 调用f的时候,f只是被声明了,还没有被赋值,等于undefined,所以会报错。

(3) Function() 

三、函数的调用

函数会在什么情况下调用:

1、当事件发生时(点击按钮,例如轮播图中的小圆点)

2、当js代码调用时(cfb();)

3、函数创建后自动调用(如下)

 

  • 立即调用的函数表达式(IIFE)

        IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的  JavaScript 函数

  • 通常情况下,只对匿名函数使用这种“立即执行的函数表达式

立即调用的函数表达式目的有两个

一.是不必为函数命名,避免了污染全局变量;

二.是IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。

 4、间接调用,通过它们的call()和apply()方法间接调用   

四、函数的参数

形参:形式上的参数,没有实际值形参只作用于函数内部(函数体后面()中的参数是形参)

实参:实际上有值的参数调用函数的时候()中传入的参数值是实参

注意:实参传多了不会出错,代码只会对应的取前面的参数;

       实参传少了,会出错输出NAN(非数值类型)

五、全局变量和局部变量,作用域(scope)

1、函数外部的变量函数中可以使用(全局变量)

2、但是函数中的变量,函数外不能使用。(局部变量)

3、函数内部不用var声明,直接赋值方式声明的变量是全局变量。

六、带有返回值的函数

  1. Return返回执行结果,不会在页面中显示,需要用变量来接收
  2. 函数遇到return,会立即返回结果,并终止函数
  3. 返回值类型可以是任意类型,也可以是一个对象,也可以是一个函数

七、将函数作为参数(回调函数)

常见的回调函数?(面试)

  1. Dom事件回调函数
  2. 定时器回调函数
  3. Ajax回调请求
  4. 生命周期回调函数

八、匿名函数

匿名函数:就是没有函数名

1、第一种匿名函数:函数没有函数名,而是直接赋值给一个变量通过变量调用或者直接调用

注:1.匿名函数的调用,必须放在函数声明之后

2.普通函数调用,是可以在函数声明之前的

2、第二种匿名函数:完全匿名也没有变量

1.自调用

2.当事件发生时调用

3.函数中调用

九、递归函数

函数可以调用自身,这就是递归(recursion)

递归函数就是自己调自己

十、函数的内部属性和方法

1.Arguments

Arguments是一个函数中自带的对象

arguments 是一个对应于传递给函数的参数(实参)的类数组对象。

arguments.length  传递给函数的参数数量。(实参)

函数的length属性是只读属性,代表函数形参的数量,也就是在函数定义时给出的形参个数。

2.prototype属性(原型) 

  1. 每一个函数都包含一个prototype属性,这个属性指向一个对象的引用,这个对象称做“原型对象”(prototype object)。
  2. prototype 属性允许您向对象添加属性和方法                                                                  
  3. 注意: Prototype 是全局属性,适用于所有的Javascript对象。
  4. 这个prototype的属性值是一个对象(属性的集合,再次强调!),默认的只有一个叫做constructor的属性,指向这个函数本身

3.函数对象自带的call()方法和apply()方法

每个函数都包含两个非继承而来的方法:call()方法和apply()方法。

定义:call和apply可以用来重新定义函数的执行环境,也就是this的指向;call和apply都是为了改变某个函数运行时的context,即上下文而存在的,换句话说,就是为了改变函数体内部this的指向。

call()

调用一个对象的方法,用另一个对象替换当前对象,可以继承另外一个对象的属性,它的语法是:

apply()

和call()方法一样,只是参数列表不同,语法:

//obj:这个对象将代替Function类里this对象
//argArray:这个是数组,它将作为参数传给Function
//说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个TypeError,如果没有提供argArray和obj任何一个参数,那么Global对象将用作obj。
function add(a, b) {
    return a + b;
}
function sub(a, b) {
    return a - b;
}

function People(name, age) {
    this.name = name;
    this.age = age;
}
//为什么add.call(sub, 2, 1)的执行结果是3呢,因为call()方法改变了this的指向,使得sub可以调用add的方法,
//也就是用sub去执行add中的内容
//再来看一个例子:

function Student(name, age, grade) {
    People.call(this, name, age);
    this.grade = grade;
}

var student = new Student('小明', 21, '大三');
console.log(student.name + student.age + student.grade);//小明21大三

//总结一句话就是call()可以让括号里的对象来继承括号外函数的属性。

总结一句话就是call()可以让括号里的对象来继承括号外函数的属性。

console.log(add.call(sub, 2, 1));//3

  • Apply()和call()中的参数是谁,那么this就指向谁

## 作用

共同作用:修改this指向

其次就是它们不同的传参方式:注意上一句话中说他们的作用时有两个关键词 ‘函数’和‘this’,想要修改this 的指向,那么必然有一个this修改后的指向,而函数必然后关系到传参问题:call方法可以传给该函数的参数分别作为自己的多个参数,而apply方法必须将传给该函数的参数合并成一个数组作为自己的一个参数:

## 区别​

不同之处是:

  1. call() 方法接受的是**一个参数列表**
  2. apply() 方法接受的是**一个包含多个参数的数组**。

如果要使用数组而不是参数列表,则 apply() 方法非常方便。

  1. person.fullName.apply(person1, ["Oslo", "Norway"]);
  2. person.fullName.call(person1, "Oslo", "Norway");

十一、构造函数

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

  •  new 在执行时会做四件事情: (重点)

在内存中创建一个新的空对象。

让 this 指向这个新的对象。

执行构造函数里面的代码,给这个新对象添加属性和方法。

返回这个新对象(所以构造函数里面不需要 return )

  •  this (重点)

this (重点)

1.this出现在全局函数中,永远指向window ;

2.当某个函数为对象的一个属性时,在这个函数内部this指向这个对象;

3.this出现在构造函数中,指向构造函数新创建的对象;

函数内部使用this,谁调用的函数this指向谁;

十二、原型

原型是function 对象的一个属性,它定义了构造函数制造对象的公共祖先,通过该构造函数产生的对象可以继承该原型的属性和方法,原型也是对象。prototype原型最大的作用,共享属性和方法

JavaScript对象具有“自有属性”,也有一些属性是从原型对象Object.prototype 继承而来的。

如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”。

十三、原型链

1)每个函数function都有一个prototype,即显式原型(属性)

prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数

2)每个实例对象都有一个__proto__,可称为隐式原型(属性)

3)对象的隐式原型的值为其对应构造函数的显式原型的值

4)内存结构(图)

十四、操作符

(1)instanceof运算符

instanceof运算符返回一个布尔值,表示指定对象是否为某个构造函数的实例。

instanceof运算符的左边是实例对象,右边是构造函数。它的运算实质是检查右边构建函数的原型对象,是否在左边对象的原型链上。

(2)检测一个对象是否是另一个对象的原型,可以使用isPrototypeOf()方法。

isPrototypeOf() 方法用来检测一个对象是否存在于另一个对象的原型链中,如果存在就返回 true,否则就返回 false

(3)Object.getPrototypeOf()

Object.getPrototypeOf方法返回一个对象的原型。这是获取原型对象的标准方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值