摘要:类型类型是的引用类型之一通过类型创建对象在中函数也以对象的形式存在每个函数都是一个对象构造函数函数除了用函数定义语句和字面量表达式两种方式定义之外还可以通过类型进行定义函数的参数和函数体都是以字符串形式传递给的通过类型定义函数的效率远不如函
Function类型
Function类型是JS的引用类型之一 通过Function类型创建Function对象
在JS中 函数也以对象的形式存在
每个函数都是一个Function对象
console.log(Function instanceof Function) //true console.log(Function instanceof Object) //true console.log(Object instanceof Function) //true构造函数
函数除了用函数定义语句和字面量表达式两种方式定义之外 还可以通过Funcion类型进行定义
函数的参数和函数体都是以字符串形式传递给Function的
var fun = new Function ("num","console.log(num)"); fun(100); //100
通过Function类型定义函数的效率远不如函数定义语句和字面量表达式的定义
定义函数的三种方式之间存在一定差别
函数定义语句:执行时函数名被提前声明 不存在效率问题
字面量表达式:函数体固定 无法动态执行 不存在效率问题
Function类型定义 函数体是字符串 可以动态执行 效率较低
Function的apply()方法apply方法可以劫持另外一个对象的方法,继承另外一个对象的属性.
Function.apply(obj,arguments)方法能接收两个参数(可选):
obj:这个对象将代替Function类里this对象
arguments:这个参数是数组,它将作为参数传给Function
如果没有obj参数 那么Global对象被用作obj
//定义一个人类 function Person(name,age) { this.name=name; this.age=age; } //定义一个男人 function Man(name,age,hobby) { Person.apply(this,arguments); //this代表的是man arguments是一个数组 也就是["Sicong",30,"撕逼"] this.hobby=hobby; } var man=new Man("Sicong",30,"撕逼"); console.log("name:"+man.name +" "+ "age:"+man.age +" "+"hobby:"+man.hobby); //name:SicongWang age:30 hobby:撕逼 //用Man去执行Person这个类里面的内容,在Person这个类里面存在this.name等语句,这样就将属性创建到了student对象里面Function的call()方法
call方法与apply类似 只是第二个参数不是数组
//定义一个人类 function Person(name,age) { this.name=name; this.age=age; } //定义一个woman function Woman(name,age,hobby) { Person.call(this,name,age); //this代表的是woman this.hobby=hobby; } var woman=new Woman("TimoFeng",18,"唱歌"); console.log("name:"+woman.name +" "+ "age:"+woman.age +" "+"hobby:"+woman.hobby); //name:TimoFeng age:18 hobby:唱歌Function的bind()方法
bind方法与call和apply类似 第一个参数都是this要指向的对象 利用后续参数传参数
不同的是bind是返回对应的函数 可以稍后调用;call和apply是立即调用
var fn=function () { console.log(this.x) }; var foo={ x:3 }; fn(); //undefined console.log(fn.bind(foo)); //ƒ () { // console.log(this.x) } // 此时this已经指向了foo,但是用bind()方法并不会立即执行,而是创建一个函 // 数 如果要直接调用的话 可以 bar.bind(foo)() var result=fn.bind(foo); result(); //3递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数
递归函数的优点是定义简单,逻辑清晰 所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰
递归调用的次数过多,会导致栈溢出 使用过深会造成死循环
var num=function(x){ if(x == 1){ return 1; } else{ return x*num(x-1); } } console.log(num(5)) //120 /* 计算过程为: ---> num(5) ---> 5 * num(4) ---> 5 * (4 * num(3)) ---> 5 * (4 * (3 * num(2))) ---> 5 * (4 * (3 * (2 * num(1)))) ---> 5 * (4 * (3 * (2 * 1))) 只有n=1时才特殊处理 ---> 5 * (4 * (3 * 2)) ---> 5 * (4 * 6) ---> 5 * 24 ---> 120 */回调函数
一个函数作为参数传给另一个函数 我们把另一个函数称为回调函数
通俗的说回调函数有3个特点: 1).你定义的 2).你没有调用 3).但最后执行了
回调函数的优点:
- 可以在未命名的情况下传递函数 节省全局变量 - 将另一个函数调用操作委托给另一个函数 - 有助于提升性能
$("btn").click(function(){ //click方法就是一个回调函数 alert("我是一个按钮") })自调用函数
自调用函数 声明完了,马上进行调用,只能使用一次
(function(num1,num2){ console.log(num1+num2) })(10,20) //30作用域和作用域链
作用域: 一块代码区域, 在编写时就确定, 不会再变化
作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量
分为全局作用域和函数(局部)作用域
作用:
作用域: 隔离变量, 可以在不同作用域定义同名的变量不冲突
作用域链: 查找变量
var num1=10; //全局变量 function fn1(){ var num2=20; //fn1作用域的局部变量 function fn2(){ var num3=30; //fn2作用域的局部变量 function fn3(){ var num4=40; //fn3作用域的局部变量 console.log(num1); //10 console.log(num2); //20 console.log(num3); //30 console.log(num4); //40 } fn3(); console.log(num1); //10 console.log(num2); //20 console.log(num3); //30 console.log(num4); //num4 is not defined } fn2(); console.log(num1); //10 console.log(num2); //20 console.log(num3); //num3 is not defined console.log(num4); //num4 is not defined } fn1()闭包函数
当嵌套的内部函数引用了外部函数的变量时就产生了闭包
闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
作用:
延长局部变量的生命周期
让函数外部能操作内部的局部变量
避免污染全局命名空间
缺点:
变量占用内存的时间可能会过长
可能导致内存泄露(占用的内存没有及时释放
内存泄露积累多了就容易导致内存溢出)
function fn1() { var a = 2; function fn2() { a++; console.log(a); //3 4 } return fn2; } var f = fn1(); f(); f();
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/108229.html
摘要:有个例外他就是。看左侧对象的原型链上是否有第一步得到。将各内置引用类型的指向。用实例化出,,以及的行为并挂载。实例化内置对象以及至此,所有内置类型构建完成。最后的最后,你还对是现有还是现有有想法了吗以上均为个人查阅及实践总结的观点。 来个摸底测试,说出以下每个表达式的结果 function F(){}; var o = {}; typeof F; typeof o; typeof F...
摘要:如图反而,由于这些的都是继承自,所以原型链拐向了。因此这样一个实例,他顺着原型链是找到了如图选学内容如果我们刨根问底,去寻找和的根源的话,那这个问题又稍微有点复杂了。 基本类型 Number, Boolean, String, null, undefined 什么样的变量是 undefined 声明了变量却没赋值 未声明的变量 包装类型 其实js里面也有像java,c#里所谓的包装...
摘要:对象类型常见的有,,,正则新增自己提供的乐行判断如果不对对象做严格区分使用。的实现使用了原型继承的表示左表达式,表示右表达式,它是用是否等于来判断对象的类型的。常见框架和库的实数据类型判断测试这里将的实现原理抽取出来,用原生实现。 JavaScript一共有六种数据类型,分为原始类型(又名基本类型)和对象类型(又名引用类型) 原始类型有五种,分别为number,string,boole...
摘要:本文章主要总结一下数据类型的识别判断方法最后封装一个函数,可以判别所有的类型数据类型基本类型类型该类型只有一个值,即小写,在使用声明变量但是未对其加以初始化时,这个变量的值就是。 *本文章主要总结一下js数据类型的识别判断方法tyoeofinstanceofObject.prototype.toString.callconstructor最后封装一个函数,可以判别所有的类型* 1.数据...
摘要:面向对象高级继承模式一原型链继承方式原型链继承流程定义父类型构造函数。缺点无法避免构造函数模式存在的问题方法都在构造函数中定义,无法函数复用。六寄生组合式继承在这里重复一下组合继承的代码组合继承最大的缺点是会调用两次父构造函数。 JavaScript 面向对象高级——继承模式 一、原型链继承 方式1: 原型链继承 (1)流程: 1、定义父类型构造函数。 ...
摘要:注意基本变量类型不是对象类型,只有基本包装类型才是对象类型。至于显示的原型,在里用属性表示,这个是原型继承的基础知识,在这里就不在叙述了。 前言 如果你要开发一个复杂的产品,那么肯定少不了使用面向对象机制,当然也避不开 Javascript 里面的继承,instanceof 运算符是原生 Javascript 语言中用来判断实例继承的操作符。所以我们有必要深入理解该运算符! inst...
阅读 2418·2021-10-11 10:57
阅读 1274·2021-10-09 09:59
阅读 1986·2019-08-30 15:53
阅读 3206·2019-08-30 15:53
阅读 1000·2019-08-30 15:45
阅读 727·2019-08-30 15:44
阅读 3432·2019-08-30 14:24
阅读 945·2019-08-30 14:21