72 lines
2.2 KiB
JavaScript
72 lines
2.2 KiB
JavaScript
|
|
describe("named function expression scoping", () => {
|
||
|
|
test("name is visible inside function body", () => {
|
||
|
|
const f = function factorial(n) {
|
||
|
|
if (n <= 1) return 1;
|
||
|
|
return n * factorial(n - 1);
|
||
|
|
};
|
||
|
|
expect(f(5)).toBe(120);
|
||
|
|
});
|
||
|
|
|
||
|
|
test("name is not visible outside function body", () => {
|
||
|
|
const f = function inner() {
|
||
|
|
return 42;
|
||
|
|
};
|
||
|
|
expect(() => inner).toThrowWithMessage(ReferenceError, "'inner' is not defined");
|
||
|
|
});
|
||
|
|
|
||
|
|
test("name binding is immutable inside function", () => {
|
||
|
|
const f = function immutableName() {
|
||
|
|
immutableName = "changed";
|
||
|
|
return typeof immutableName;
|
||
|
|
};
|
||
|
|
expect(f()).toBe("function");
|
||
|
|
});
|
||
|
|
|
||
|
|
test("outer variable with same name is shadowed inside", () => {
|
||
|
|
let shadow = "outer";
|
||
|
|
const f = function shadow() {
|
||
|
|
return typeof shadow;
|
||
|
|
};
|
||
|
|
expect(shadow).toBe("outer");
|
||
|
|
expect(f()).toBe("function");
|
||
|
|
});
|
||
|
|
|
||
|
|
test("assignment to outer variable with same name works", () => {
|
||
|
|
let outer;
|
||
|
|
outer = function outer() {
|
||
|
|
return outer.name;
|
||
|
|
};
|
||
|
|
expect(outer()).toBe("outer");
|
||
|
|
expect(typeof outer).toBe("function");
|
||
|
|
});
|
||
|
|
|
||
|
|
test("property access on outer variable with same name works", () => {
|
||
|
|
let Foo;
|
||
|
|
Foo = function Foo() {};
|
||
|
|
Foo.bar = 42;
|
||
|
|
expect(Foo.bar).toBe(42);
|
||
|
|
});
|
||
|
|
|
||
|
|
test("nested named function expressions", () => {
|
||
|
|
const outer = function outerFn() {
|
||
|
|
const inner = function innerFn() {
|
||
|
|
return typeof outerFn + "," + typeof innerFn;
|
||
|
|
};
|
||
|
|
return inner();
|
||
|
|
};
|
||
|
|
expect(outer()).toBe("function,function");
|
||
|
|
});
|
||
|
|
|
||
|
|
test("same name in nested function expressions", () => {
|
||
|
|
const outer = function sameName() {
|
||
|
|
const inner = function sameName() {
|
||
|
|
return sameName.length;
|
||
|
|
};
|
||
|
|
return [sameName.length, inner()];
|
||
|
|
};
|
||
|
|
const result = outer();
|
||
|
|
expect(result[0]).toBe(0); // outer sameName
|
||
|
|
expect(result[1]).toBe(0); // inner sameName (shadows outer)
|
||
|
|
});
|
||
|
|
});
|