Javascript 无嵌套函数的闭包

Javascript 无嵌套函数的闭包,javascript,closures,Javascript,Closures,到目前为止,我对闭包的理解是,如果一个函数返回一个函数,那么返回的函数(对象)会记住其(词法)父函数作用域的上下文,我正在考虑一个场景,在这个场景中,闭包可以在不实现嵌套函数的情况下实现 下面的代码就是一个很好的例子。我在这里所做的是: 我使用了一个构造函数来创建对象,并使用了内部定义的方法toString()中传递给它的参数 现在我创建了两个对象,两个对象都有各自的id、name、madeInYear副本 请注意,我可以通过使用productId,productName,productOrig

到目前为止,我对闭包的理解是,如果一个函数返回一个函数,那么返回的函数(对象)会记住其(词法)父函数作用域的上下文,我正在考虑一个场景,在这个场景中,闭包可以在不实现嵌套函数的情况下实现

下面的代码就是一个很好的例子。我在这里所做的是:

我使用了一个构造函数来创建对象,并使用了内部定义的方法
toString()
中传递给它的参数

现在我创建了两个对象,两个对象都有各自的
id、name、madeInYear
副本

请注意,我可以通过使用
productId,productName,productOriginDate
获得相同的结果,但为了便于结束,我编写了如下代码片段

我观察到的另一件有趣的事情是,我可以访问
productId
,但不能访问
id
。这是否意味着它们不是在对象上下文中创建的

function f1(id,name,madeInYear)
{
this.productId=id;
this.productName=name;
this.productOriginDate=madeInYear;

this.toString=function()
{
    console.log("Function Parameters:"+id+" "+name+" "+madeInYear);
    console.log("Objects Method:"+this.productId+" "+this.productName+" "+this.productOriginDate);
}

}

var obj1=new f1(1,"Parker Pen","2001");
var obj2=new f1(2,"Jetter",2000);

obj1.toString();
obj2.toString();
obj1.productId;
obj2.productId;
输出

Function Parameters:1 Parker Pen 2001

Objects Method:1 Parker Pen 2001

Function Parameters:2 Jetter 2000

Objects Method:2 Jetter 2000

1

2

闭包定义为从定义函数的词法上下文访问局部变量,而该函数是在该上下文之外调用的

因此,必须有一个函数来创建适当的闭包。您可以使用其他具有局部变量的函数替换外部函数,这在ES6中是可能的,它具有块作用域和
let
声明:

{
    let local = 3
    function f() {
        return local
    }
}
console.log(local) // undefined
console.log(f())   // 3

闭包定义为从定义函数的词法上下文访问局部变量,而该函数是在该上下文之外调用的

因此,必须有一个函数来创建适当的闭包。您可以使用其他具有局部变量的函数替换外部函数,这在ES6中是可能的,它具有块作用域和
let
声明:

{
    let local = 3
    function f() {
        return local
    }
}
console.log(local) // undefined
console.log(f())   // 3


从技术上讲,这不是一种关闭;这是一个。是什么让你认为你不能访问
id
?您的输出看起来工作正常。我可以访问studentId而不是id.applologies..其产品id从技术上讲这不是一个闭包;这是一个。是什么让你认为你不能访问
id
?您的输出看起来工作正常。我可以访问studentId而不是id.applologies..它的ProductId如果我创建五个对象会怎么样。我们肯定会有5份身份证、姓名、madeinYear的复印件。每个对象将保留id、名称、年份的引用,而不保留其自己的productid、productName、productMadeInYear。因此,如果m没有错,闭包说记住上下文,这里每个对象都会记住上下文。请纠正我的错误如果你的构造函数改变了它的一个闭包变量的值,那么下次你调用构造函数时,它会看到修改后的值。不涉及复制。闭包是定义函数的原始上下文。复制发生在您将值分配给对象自己的属性(
this.id
,等等)时,并且您正在显式地执行此操作。Touffy我想我无法澄清我提到的内容。可能是因为我使用了“复制”一词。我的意思是:当我创建5个对象时,构造函数将被调用5次。每次调用构造函数时,都会创建id、name、madeInYear,因此每个对象都会引用这3个参数。因此,每个对象都将引用各自的id、名称、madeInYear以及自己的producttId、productName、productOriginDate。因此,我们总共有6*5=30个变量。这三个参数永远不会被破坏,因为我在toString方法中引用了它们,因此我实现了闭包。如果我创建五个对象呢。我们肯定会有5份身份证、姓名、madeinYear的复印件。每个对象将保留id、名称、年份的引用,而不保留其自己的productid、productName、productMadeInYear。因此,如果m没有错,闭包说记住上下文,这里每个对象都会记住上下文。请纠正我的错误如果你的构造函数改变了它的一个闭包变量的值,那么下次你调用构造函数时,它会看到修改后的值。不涉及复制。闭包是定义函数的原始上下文。复制发生在您将值分配给对象自己的属性(
this.id
,等等)时,并且您正在显式地执行此操作。Touffy我想我无法澄清我提到的内容。可能是因为我使用了“复制”一词。我的意思是:当我创建5个对象时,构造函数将被调用5次。每次调用构造函数时,都会创建id、name、madeInYear,因此每个对象都会引用这3个参数。因此,每个对象都将引用各自的id、名称、madeInYear以及自己的producttId、productName、productOriginDate。因此我们总共有6*5=30个变量。这三个参数永远不会被破坏,因为我在toString方法中引用了它们,因此我实现了闭包。