解决掉你心中 js function与Function的关系的疑问
前言
在网上有很多关于js function 与 Function直接关系的文章。
但是我感觉过于抽象化了,那么如何是具体化的解释?
正文部分为个人理解部分,如有不对望指出。
正文
<script>
if((function(){}).constructor === Function)
{
console.log(true);
}
</script>
我写了一段这个代码,答案为true。
这就是function 与 Function的关系。
看下Function的定义:
Function 构造函数创建一个新的 Function 对象。直接调用此构造函数可用动态创建函数,但会遭遇来自 eval 的安全问题和相对较小的性能问题。然而,与 eval 不同的是,Function 构造函数只在全局作用域中运行。
然后还给出了这样一个结论:
每个 JavaScript 函数实际上都是一个 Function 对象。
重新理解一下,Function的定义。
第一句话很好理解,就是可以创建一个Function对象。第二句好也好理解,就是会有安全漏洞和性能问题,详细部分可看eval的安全问题,至于为什么低效,官方解释是:因为使用后者创建的函数是跟其他代码一起解析的。
第三句话,什么叫"Function 构造函数只在全局作用域中运行"?
var func = new Function("alert(x+y);");
var test = function () {
var x=1,y=2;
func();
eval("x+y");
}
就是func()运行会报错。而eval("x+y")是成功的。
因为func()是在全局作用域中运行。
如果是这样:
var x=1,y=2;
var func = new Function("alert(x+y);");
var test = function () {
var x=1,y=2;
func();
eval("x+y");
}
test();
那么会弹出3;
当然这里说eval是在局部变量中运行也比较绝对,因为eval的引用变量是在全局中运行的。
var global=eval;
global("x+y");
这样就在全局中运行,好吧,这不是该篇的重点。
那么这种Function 对象和申明函数有什么区别呢?前面已经说明了,Function对象是在全局中运行,而声明函数是在局部中运行。
我找了一个例子:
var x = 10;
function createFunction1() {
var x = 20;
return new Function('return x;'); // 这里的 x 指向最上面全局作用域内的 x
}
function createFunction2() {
var x = 20;
function f() {
return x; // 这里的 x 指向上方本地作用域内的 x
}
return f;
}
var f1 = createFunction1();
console.log(f1()); // 10
var f2 = createFunction2();
console.log(f2()); // 20
看到这里,以为结束了?下面是本文的核心思想部分。
我们如何才能够,用function的方式建立出Function对象的效果?或者说我们如何模拟new Function() 到底发生了什么。
var x=1,y=2;
var func = new Function("alert(x+y);");
var func1= function ()
{
alert(x+y);
}
console.log(func);
console.log(func1);
打印出来func,是一个匿名的函数。
匿名函数自带是闭包效果,在这里我似乎找到了答案,现在我们就来模拟出new Function();
function main() {
var x = 5;
var y = 6;
FunctionObj = function () {
alert(x + y);
};
function func() {
var x = 1;
var y = 2;
var Newfunc = FunctionObj;
Newfunc();
}
func();
}
main();
FunctionObj();
弹出的结果是11,另一个弹出的还是11;
在这里我假设启动的是main主函数,x与y是全局变量。
然后在func中的:
var func = FunctionObj;
func();
假设为new Function(),也就是说去假设构建一个Function 对象。
这样实现的其实就是在全局变量中创建了FunctionObj变量,然后赋值给了func,然后再执行func的时候自然就在main变量中了,因为匿名函数本身就闭包。
对应为:
var x=5;
var y=6;
function func()
{
var x=1;
var y=2;
var NewFunc= new Function("alert(x+y)");
NewFunc();
}
func();
继续变化一下,模拟Function 做了什么:
var x=5;
var y=6;
function func()
{
var x=1;
var y=2;
var NewFunc= Functionsimulation();
NewFunc();
}
function Functionsimulation()
{
var global=eval;
return eval("(function(){return function(){alert(x+y)}})()");
}
func();
弹出的结果依然是:11;
总结
回过头来,再看一下这段话:
每个 JavaScript 函数实际上都是一个 Function 对象。
new Function 只是将匿名包,绑定到了一个全局变量了,这样它的this永远固定,运行时,永远是在全局中运行。
至于声明函数,因为是动态的运行,所以我们访问的以局部优先,也可以理解为绑定的为局部变量。
以上是个人理解,如有不对望指出。
解决掉你心中 js function与Function的关系的疑问的更多相关文章
- JS 语言的Function 解析
1.最基本的作为一个本本分分的函数声明使用. 复制代码代码如下: function func(){} 或 var func=function(){}; 2.作为一个类构造器使用: 复制代码代码如下: ...
- js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( ))
( function(){…} )() ( function (){…} () ) 是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达 ...
- js 里面的 function 与 Function
function 是 js 的标识符 Function 是 js 里面的一个 构造函数 1.new function 与 new Function 的区别 new 运算符在 js 里面是 创建一个自定 ...
- JS里面function和Function的区别
js里Function 与 function的不一样的,不仅仅是大小写的问题. 简单点说:大写的Function是一个类 ,而小写的function是一个对象. Function是一个构造器,func ...
- js的函数-function
function函数 function的英文是[功能],[数] 函数:职责:盛大的集会的意思 在js里,就是函数的意思.在Java里叫做方法. 定义函数 function fun(参数){ //函数体 ...
- js in depth: closure function & curly function
js in depth: closure function & curly function 闭包, 科里化 new js 构造函数 实例化, 不需要 new var num = new Ar ...
- js中使用function定义类、实例化,函数的调用方法
function Test002(name, age){ name, age, this.printInfo = function(){ //定义的公有方法 console.log(name, age ...
- JS原型的问题Object和Function到底是什么关系
var F = function(){}; Objcert.prototype.a = function(){}; Function.prototype.b = function(){}; F 既能访 ...
- js中的(function(){})()立即执行
( function(){-} )() 和 ( function (){-} () ) 是两种javascript立即执行函数的常见写法,要理解立即执行函数,需要先理解一些函数的基本概念. 函数声明. ...
随机推荐
- kubernetes concepts (一)
Concepts The Concepts section helps you learn about the parts of the Kubernetes system and the abstr ...
- AVR单片机教程——小结
本文隶属于AVR单片机教程系列. 第一期挺让我失望的,是我太菜,没有把想讲的都讲出来.经常写了很多,然后一点一点删掉,最后就没多少了. 而且感觉难度不合适,处于很尴尬的位置.讲得简单,难的丢给库, ...
- [题解][Codeforces]Codeforces Round #602 (Div. 1) 简要题解
orz djq_cpp lgm A 题意 给定一个分别含有 \(\frac n2\) 个左括号和右括号的括号序列 每次可以将序列的一个区间翻转 求一个不超过 \(n\) 次的操作方案,使得操作完之后的 ...
- CSS-04-层叠选择器
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- python调用matlab脚本
在MATLAB和Python之间建个接口,从Python中调用MATLAB脚本或者是MATLAB的函数.内容不是很难,毕竟现成的接口已经有了,在这儿记录一下API使用的一些事项. 注:本篇使用的是MA ...
- HTML简介介绍
网页概述 网页:纯文本格式的文件:(以村文本格式编写,后缀名改为HTML的文本文件) ---- 网站:多个网页的集合: ---- 主页:打开网站后显示的第一个页面: ---- 浏览器:将纯文本格式的文 ...
- 我的一个react路由之旅(步骤及详图)
今天开始react一个重要部分的xiao~习,路由~(过程截图,最后附代码) 以下代码只能骗糊涂蛋子,没错,就是我自己,不要打算让我敲出多高级的东西~ 理论性知识几乎没有,请不要打算让我给你说原理啥的 ...
- python学习Day06--编码
[主要内容] 1. is 和 == 区别 id()函数 == 判断两边的值 is 判断内存地址回顾编码: 1. ASCII: 英文, 特殊字符, 数字, 8bit, 1byte 2. GBK: 中文 ...
- 注册并加入dn42网络的方法
简介 https://dn42.net/howto/Getting-started 注册要求: 一个24小时运行的linux/BSD设备 该设备必须支持创建隧道,例如GRE,OpenVpn,IPSec ...
- vue初始化、数据处理、组件传参、路由传参、全局定义CSS与JS、组件生命周期
目录 项目初始化 组件数据局部化处理 子组件 父组件 路由逻辑跳转 案例 组件传参 父传子 子组件 父组件 子传父 子组件 父组件 组件的生命周期钩子 路由传参 第一种 配置:router/index ...