本文主要是介绍6.25 js笔记补充,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
闭包的补充知识
闭包是指有权访问另一个函数作用域中的变量的函数
function f1(){var n = 123;function f2(){ //f2是一个闭包alert(n)} return f2;}js链式作用域:子对象会一级一级向上寻找所有父对象的变量,反之不行。
js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量。
闭包:f2可以读取f1中的变量,只要把f2作为返回值,就可以在f1外读取f1内部变
原因:f1是f2的父函数,f2被赋给了一个全局变量,f2始终存在内存中,f2的存在依赖f1,因此f1也始终存在内存中,不会在调用结束后,被垃圾回收机制回收。
闭包概念
能够读取其他函数内部变量的函数。
或简单理解为定义在一个函数内部的函数,内部函数持有外部函数内变量的引用。
闭包用途
1、读取函数内部的变量
2、让这些变量的值始终保持在内存中。不会再f1调用后被自动清除。
3、方便调用上下文的局部变量。利于代码封装。
对象的可扩展性
Object.preventExtensions()
说明:
对象一旦设置不为不可扩展就不能转换为可扩展了
Object.preventExtensions只会影响对象本身的可扩展性,所以依然还是可以给对象原型添加属性。
const log = console.log;var aa = {};Object.preventExtensions(aa);aa.x = 1;log(aa.x)
结果: undefined
检测对象是否是可扩展的
Object.isExtensible()
const log = console.log;var aa = {};var bb = {};Object.preventExtensions(aa);log(Object.isExtensible(aa))log(Object.isExtensible(bb))
结果:
false
true
将对象封闭(sealed)
Object.seal()
说明:
- Object.seal不仅可以设置对象的可扩展性,还可以设置对象的所有自有属性的可配置性
- 将对象设置为不可扩展并且不可配置,也就是说不能给这个对象添加新属性,而且已有的属性不能删除或者配置。
- 不过这些属性可写特性依然是可以配置的
const log = console.log;var aa = {y: 2};Object.seal(aa);aa.x = 1;log(aa.x);log(Object.getOwnPropertyDescriptor(aa, 'y'))Object.defineProperty(aa, 'y', {writable: false,})log(Object.getOwnPropertyDescriptor(aa, 'y'))
检测对象是否被封闭
Object.isSealed()
const log = console.log;var aa = {};var bb = {};Object.seal(aa);log(Object.isSealed(aa));log(Object.isSealed(bb))
将对象冻结(freeze)
Object.freeze()
说明:
- freeze不仅仅可以将对象设置为不可扩展和所有属性为不可配置,并且会将所有对象属性设置为只读。
- 如果存取器属性具有setter方法,则不会受到影响,仍然可以通过此方法给属性赋值。
const log = console.log;var aa = {x: 1};Object.freeze(aa);log(Object.getOwnPropertyDescriptor(aa, 'x'))
小结:
Function对象知识补充
function定义
1.function fname(test){ alert(""+test); }
2.通过Function的函数的构造器进行函数对象的定义。
var fname = new Function(“test”, “alert(’’+test);”); 第一个参数实际上是表示要传入函数中的参数,二第二个参数表示的是当前的函数要执行的过程。两个参数实际上都是string类型的。
3.var fname = function(test){alert(""+test);}
第一种方法实际上是为函数命名为fname,而二三种方法使用起来实际上是把一个匿名函数赋值给一个变量。使用第二种方法来定义函数的时候,实际上就是调用构造函数并在每次解析的时候都会重新读取并创建一新的函数对象,由此可见当在循环体中调用这样的函数的时候会是十分的低效的,还有一点就是,当我们使用其创建一个函数对象的时候,当在函数内部调用它的时候,其实他并不会用函数内部定义的变量。而是只能使用全局变量。
Function对象的定义和内容
首先是我们最为常用的内容arguments对象。他的定义是,一个类似于数组的对象,对应的是传递给函数对象的属性。arguments对象是一个所有的函数内部都可以用的函数内部变量。当我们调用函数的时候,他会存储我们传输进来的参数的数据的。如下端的代码。
1 function test(){
2 if(arguments[0]){
3 alert("arguments:",+arguments[0]);
4 }
5 }
6 test("a");//当前页面中会显示出一个弹出框并显示arguments:a
所以由上面可以看出,arguments对象的使用方式和array是十分的相像的。为什么说他只是类似数组对象呢,因为他仅仅只有length属性但并没有array的其他属性和方法。
当然在arguments对象中也是有一些其自己的属性的,如下
- callee,属性存储的是当前的调用的函数对象。当我们使用匿名函数的时候,如果需要调用存储当前的arguments对象的方法对象,此时可以使用当前属性。但是在ECM5中是阻止使用这一属性的。这样做的原因是,函数命名来调用函数的实现是优于这种方式的。
- caller,这一属性只有当函数正在执行的情况之下才会被定义。当然其返回的内容是当前的和toString方法是一样的,为function的反编译文本。但是实际上在使用的时候返回便以文本之后,js有解析成为函数对象之后执行,所以说,这一属性实际上还是返回函数本身。但是这一属性在ECM5中已经被删除了。
- length属性,是初始化的时候读取当前函数中的参数后获取的值。所以函数的length属性的值其实就和arguments.length的值的大小是一样的。
- prototype属性,表示的是当前的function对象的原型对象。也可以了几位当前的函数对象继承了原型对象的属性和方法。
当然对于函数对象js中也是有定义一些基本方法的。
apply方法,制定方法替换当前的this指针,并用传入的对象中的数据替换当前函数的参数值。如:
function test(){alert("" + this);
}function testTwo(a){console.log("this:"+this);console.log("a:"+a);
}testTwo.apply(test, [1]);//输出的效果是this:function test(){ alert("" + this);} 与 a:1
实际上apply是用第一个参数中的对象替换当前的函数中的this指针,并用数组参数中的数据来来替换但钱的函数调用时的参数。
bind方法,其效果是不论当前的函数怎么调用他的this指针代表的值都是一样的。
var displayArgs = function (val1, val2, val3, val4) {document.write(val1 + " " + val2 + " " + val3 + " " + val4);
}var emptyObject = {};var displayArgs2 = displayArgs.bind(emptyObject, 12, "a");displayArgs2("b", "c");// Output: 12 a b c
由上面可见实际上bind函数就有点像是绑定当前的内容和一个数据的关系。并返回一个一个可调用对象。
call方法使用效果实际上和apply方法是一样的,只是其后面传递的第二个参数不再是严格要求是数组。
这篇关于6.25 js笔记补充的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!