ජාවාස්ක්‍රිප්ට් වසා දැමීම් ක්‍රියා කරන්නේ කෙසේද?


7636

ජාවාස්ක්‍රිප්ට් වසා දැමීම් ඔවුන් සමන්විත වන සංකල්ප පිළිබඳ දැනුමක් ඇති අයෙකුට (උදාහරණයක් ලෙස කාර්යයන්, විචල්‍යයන් සහ ඒ හා සමාන) පැහැදිලි කරන්නේ කෙසේ ද?

විකිපීඩියාවේ ලබා දී ඇති යෝජනා ක්‍රම උදාහරණය මම දැක ඇත්තෙමි , නමුත් අවාසනාවකට එය උදව් වූයේ නැත.


391
මෙම සහ බොහෝ පිළිතුරු පිළිබඳ මගේ ගැටළුව නම්, ඔවුන් එය වෙත ළඟා වන්නේ ජාවාස්ක්‍රිප්ට් හි වසා දැමීම් අවශ්‍ය වන්නේ ඇයි සහ ඔබ ඒවා භාවිතා කරන ප්‍රායෝගික තත්වයන් පැහැදිලි කිරීම ආරම්භ කිරීමට වඩා වියුක්ත න්‍යායාත්මක දෘෂ්ටිකෝණයකින් ය. ඔබ අවසන් වන්නේ "නමුත්, ඇයි?" යනුවෙන් නිතරම සිතමින් ඔබට සටන් පා to කියවිය යුතු tl; dr ලිපියකි. මම සරලවම ආරම්භ කරන්නේ: වසා දැමීම යනු ජාවාස්ක්‍රිප්ට් හි පහත සඳහන් යථාර්ථයන් දෙක සමඟ කටයුතු කිරීමේ පිළිවෙලකි: a. විෂය පථය ක්‍රියාකාරී මට්ටමින් මිස බ්ලොක් මට්ටමින් සහ, ආ. ජාවාස්ක්‍රිප්ට් හි ඔබ ප්‍රායෝගිකව කරන බොහෝ දේ අසමමුහුර්ත / සිදුවීම් මත පදනම් වේ.
ජෙරමි බර්ටන්

53
EdsRedsandro එකක් නම්, එය සිදුවීම් මත පදනම් වූ කේතය ලිවීමට පහසු කරයි. HTML හෝ පවතින විශේෂාංග පිළිබඳ විශේෂතා තීරණය කිරීම සඳහා පිටුව පූරණය වන විට මම ශ්‍රිතයක් ගිනි තබමි. මට එම ශ්‍රිතය තුළ හසුරුවන්නෙකු නිර්වචනය කර සැකසිය හැකි අතර එය නැවත විමසීමෙන් තොරව හසුරුවන්නා කැඳවන සෑම අවස්ථාවකම එම සන්දර්භ තොරතුරු ලබා ගත හැකිය. ගැටළුව එක් වරක් විසඳන්න, හසුරුවන්නා නැවත කැඳවීමේදී අඩු පිරිවැය සමඟ එම හසුරුවන්නා අවශ්‍ය සෑම පිටුවකම නැවත භාවිතා කරන්න. එකම දත්ත නොමැති භාෂාවක දෙවරක් නැවත සිතියම් ගත කිරීම ඔබ දැක තිබේද? වසා දැමීම් නිසා එවැනි දේ වළක්වා ගැනීම පහසු කරයි.
එරික් රෙපන්

1
@ එරික් රෙපන් පිළිතුරට ස්තූතියි. ඇත්ත වශයෙන්ම, මෙම දෘඩ closureකේතය කියවීමට ඇති ප්‍රයෝජන ගැන මට කුතුහලයක් ඇති වූ Object Literalඅතර එය නැවත භාවිතා කරන අතර ඉහළින්ම එකම දේ අඩු කරයි, නමුත් 100% අඩු එතීමේ කේතයක් අවශ්‍ය වේ.
රෙඩ්සැන්ඩ්‍රෝ

6
ජාවා ක්‍රමලේඛකයින් සඳහා, කෙටි පිළිතුර නම් එය අභ්‍යන්තර පන්තියකට සමාන ශ්‍රිතයකි. අභ්‍යන්තර පංතියක් බාහිර පංතියේ නිදසුනක් සඳහා ව්‍යංග දර්ශකයක් ද තබා ඇති අතර එය බොහෝ දුරට එකම අරමුණක් සඳහා භාවිතා කරයි (එනම් සිදුවීම් හසුරුවන්නන් නිර්මාණය කිරීම).
බොරිස් වැන් ෂූටන්

8
මෙම ප්‍රායෝගික උදාහරණය ඉතා ප්‍රයෝජනවත් බව මට පෙනී ගියේය: youtube.com/watch?v=w1s9PgtEoJs
අභි

Answers:


7360

වසා දැමීම යනු යුගලනයකි:

  1. ශ්‍රිතයක්, සහ
  2. එම ශ්‍රිතයේ බාහිර විෂය පථයට (ශබ්දකෝෂ පරිසරය) යොමු කිරීම

ශබ්දකෝෂ පරිසරයක් යනු සෑම ක්‍රියාත්මක කිරීමේ සන්දර්භයකම (සිරස් රාමුව) කොටසක් වන අතර එය හඳුනාගැනීම් (එනම් දේශීය විචල්‍ය නම්) සහ අගයන් අතර සිතියමකි.

ජාවාස්ක්‍රිප්ට් හි සෑම ශ්‍රිතයක්ම එහි බාහිර ශබ්දකෝෂ පරිසරය වෙත යොමු කිරීමක් පවත්වා ගනී. ශ්‍රිතයක් ක්‍රියාත්මක කරන විට නිර්මාණය කරන ලද ක්‍රියාත්මක කිරීමේ සන්දර්භය වින්‍යාස කිරීමට මෙම යොමුව භාවිතා කරයි. මෙම සඳහන මඟින් ශ්‍රිතය තුළ ඇති කේතයන් ශ්‍රිතයෙන් පිටත ප්‍රකාශයට පත් කරන ලද විචල්‍යයන් "දැකීමට" හැකි වේ.

ශ්‍රිතයක් වෙනත් ශ්‍රිතයක් මගින් හැඳින්වූ ශ්‍රිතයක් මගින් නම්, එවිට බාහිර ශබ්දකෝෂ පරිසරයන් සඳහා යොමු දාමයක් නිර්මාණය වේ. මෙම දාමය විෂය පථ දාමය ලෙස හැඳින්වේ.

පහත දැක්වෙන කේතය දී, innerපසු ඇති වූ ක්රියාත්මක සන්දර්භය අයත් lexical පරිසරය සමග වසා සාදයි foo, ආයාචනා කරයි ක් වසා විචල්ය secret:

function foo() {
  const secret = Math.trunc(Math.random()*100)
  return function inner() {
    console.log(`The secret number is ${secret}.`)
  }
}
const f = foo() // `secret` is not directly accessible from outside `foo`
f() // The only way to retrieve `secret`, is to invoke `f`

වෙනත් වචන වලින් කිවහොත්: ජාවාස්ක්‍රිප්ට් හි, කාර්යයන් පුද්ගලික “රාජ්‍ය පෙට්ටියක්” වෙත යොමු කරයි, ඒවාට (සහ එකම ශබ්දකෝෂ පරිසරය තුළ ප්‍රකාශයට පත් කරන ලද වෙනත් ඕනෑම කාර්යයකට) ප්‍රවේශය ඇත. මෙම රාජ්‍ය කොටුව ශ්‍රිතයේ ඇමතුම්කරුට නොපෙනෙන අතර දත්ත සැඟවීම සහ සංයුක්ත කිරීම සඳහා විශිෂ්ට යාන්ත්‍රණයක් සපයයි.

මතක තබා ගන්න: ජාවාස්ක්‍රිප්ට් හි කාර්යයන් විචල්යයන් (පළමු පන්තියේ කාර්යයන්) මෙන් ගමන් කළ හැකිය, එයින් අදහස් වන්නේ මෙම ක්‍රියාකාරීත්වය සහ රාජ්ය යුගලය ඔබේ වැඩසටහන වටා සම්මත කළ හැකි බවයි: සී ++ හි පන්තියක උදාහරණයක් ඔබ සමත් වන ආකාරය හා සමාන වේ.

ජාවාස්ක්‍රිප්ට් වැසීම් නොතිබුනේ නම් , පරාමිති ලැයිස්තු දිගු කිරීම සහ කේත is ෝෂාකාරී වන පරිදි පැහැදිලිවම කාර්යයන් අතර වැඩි රාජ්‍යයක් සම්මත කළ යුතුය .

එබැවින්, ඔබට කිසියම් කාර්යයක් සැමවිටම පුද්ගලික රාජ්‍යයකට ප්‍රවේශ වීමට අවශ්‍ය නම්, ඔබට වසා දැමීමක් භාවිතා කළ හැකිය.

... සහ නිතර අප කරන්නේ උත්සවයකට සමඟ එක්ව රාජ්ය ඕන. උදාහරණයක් ලෙස, ජාවා හෝ සී ++ හි, ඔබ පන්තියකට පුද්ගලික නිදර්ශන විචල්‍යයක් සහ ක්‍රමයක් එකතු කරන විට, ඔබ ක්‍රියාකාරීත්වය සමඟ රාජ්‍යය සම්බන්ධ කරයි.

සී සහ වෙනත් බොහෝ පොදු භාෂාවලින්, ශ්‍රිතයක් නැවත පැමිණීමෙන් පසු, සියලු දේශීය විචල්‍යයන්ට තවදුරටත් ප්‍රවේශ විය නොහැක. ජාවාස්ක්‍රිප්ට් හි, ඔබ වෙනත් ශ්‍රිතයක් තුළ ශ්‍රිතයක් ප්‍රකාශ කරන්නේ නම්, පිටත ශ්‍රිතයේ දේශීය විචල්‍යයන් එයින් ආපසු පැමිණීමෙන් පසුව ප්‍රවේශ විය හැකිය. මේ ආකාරයට, ඉහත කේතය දී, secretමෙම උත්සවය වස්තුව ලබා පවතී inner, පසු එය ආපසු යවා ඇතfoo .

වසා දැමීමේ භාවිතයන්

ඔබට ශ්‍රිතයක් හා සම්බන්ධ පෞද්ගලික තත්වයක් අවශ්‍ය වූ විට වසා දැමීම ප්‍රයෝජනවත් වේ. මෙය ඉතා සුලභ සිදුවීමකි - සහ මතක තබා ගන්න: ජාවාස්ක්‍රිප්ට් 2015 වන තෙක් පන්ති වාක්‍ය ඛණ්ඩයක් නොතිබූ අතර එයට තවමත් පුද්ගලික ක්ෂේත්‍ර සින්ටැක්ස් නොමැත. වසා දැමීම් මෙම අවශ්‍යතාවය සපුරාලයි.

පුද්ගලික අවස්ථා විචල්‍යයන්

පහත දැක්වෙන කේතයේ, toStringමෝටර් රථයේ විස්තර මත ක්‍රියාකාරිත්වය වසා දමයි.

function Car(manufacturer, model, year, color) {
  return {
    toString() {
      return `${manufacturer} ${model} (${year}, ${color})`
    }
  }
}
const car = new Car('Aston Martin','V8 Vantage','2012','Quantum Silver')
console.log(car.toString())

ක්‍රියාකාරී වැඩසටහන්කරණය

පහත දැක්වෙන කේතය දී කාර්යය innerඉක්මවා වැසුනු fnහා args.

function curry(fn) {
  const args = []
  return function inner(arg) {
    if(args.length === fn.length) return fn(...args)
    args.push(arg)
    return inner
  }
}

function add(a, b) {
  return a + b
}

const curriedAdd = curry(add)
console.log(curriedAdd(2)(3)()) // 5

සිදුවීම්-නැඹුරු වැඩසටහන්කරණය

පහත කේතය තුළ, ශ්‍රිතය onClickවිචල්‍යයට වඩා වැසේ BACKGROUND_COLOR.

const $ = document.querySelector.bind(document)
const BACKGROUND_COLOR = 'rgba(200,200,242,1)'

function onClick() {
  $('body').style.background = BACKGROUND_COLOR
}

$('button').addEventListener('click', onClick)
<button>Set background color</button>

මොඩියුලරීකරණය

පහත දැක්වෙන උදාහරණයේ දී, සියලු ක්‍රියාත්මක කිරීමේ තොරතුරු ක්ෂණිකව ක්‍රියාත්මක වන ශ්‍රිත ප්‍රකාශනයක් තුළ සඟවා ඇත. කාර්යයන් tickහා toStringඔවුන් ඔවුන්ගේ වැඩ කටයුතු නිම කිරීමට අවශ්ය පෞද්ගලික රාජ්ය හා කාර්යයන් භාර සමීප. වසා දැමීම් මඟින් අපගේ කේතය මොඩියුලරීකරණය කිරීමට හා සංයුක්ත කිරීමට අපට හැකි වී තිබේ.

let namespace = {};

(function foo(n) {
  let numbers = []
  function format(n) {
    return Math.trunc(n)
  }
  function tick() {
    numbers.push(Math.random() * 100)
  }
  function toString() {
    return numbers.map(format)
  }
  n.counter = {
    tick,
    toString
  }
}(namespace))

const counter = namespace.counter
counter.tick()
counter.tick()
console.log(counter.toString())

උදාහරණ

උදාහරණ 1

වසා දැමීම මුල් විචල්ය සැඳහුම පවත්වාගෙන: දේශීය විචල්ය වසා පිටපත් නොවන බව මේ උදාහරණය අපට පෙන්වනවා තමන් . එය හරියට පිටත ශ්‍රිතය පිටවීමෙන් පසුව වුවද සිරස් රාමුව මතකයේ රැඳේ.

function foo() {
  let x = 42
  let inner  = function() { console.log(x) }
  x = x+1
  return inner
}
var f = foo()
f() // logs 43

උදාහරණ 2

පහත දැක්වෙන කේතය, ක්රම තුනක් log, incrementහා updateඑම lexical පරාසය පරිසරය වැඩි සියලු සමීප.

සෑම අවස්ථාවකම createObjectහැඳින්වෙන විට, නව ක්‍රියාත්මක කිරීමේ සන්දර්භයක් (සිරස් රාමුවක්) නිර්මාණය වන අතර සම්පූර්ණයෙන්ම නව විචල්‍යයක් ඇති වන අතර මෙම නව විචල්‍යයට ආසන්නව නව xශ්‍රිත සමූහයක් ( logආදිය) නිර්මාණය වේ.

function createObject() {
  let x = 42;
  return {
    log() { console.log(x) },
    increment() { x++ },
    update(value) { x = value }
  }
}

const o = createObject()
o.increment()
o.log() // 43
o.update(5)
o.log() // 5
const p = createObject()
p.log() // 42

උදාහරණ 3

ඔබ භාවිතා කරන ප්‍රකාශිත විචල්‍යයන් භාවිතා කරන්නේ නම් var, ඔබ වසා දමන්නේ කුමන විචල්‍යයද යන්න තේරුම් ගැනීමට ප්‍රවේශම් වන්න. භාවිතයෙන් ප්‍රකාශිත විචල්‍යයන් varඔසවා ඇත. නූතන ජාවාස්ක්‍රිප්ට් හි හඳුන්වාදීම letසහ const.

පහත දැක්වෙන කේතය තුළ, ලූපය වටා සෑම අවස්ථාවකම නව ශ්‍රිතයක් innerනිර්මාණය වන අතර එය අවසන් වේ i. නමුත් var iලූපයෙන් පිටත ඔසවා ඇති නිසා , මෙම සියලු අභ්‍යන්තර ශ්‍රිත එකම විචල්‍යයට වඩා සමීප වේ, එයින් අදහස් වන්නේ i(3) හි අවසාන අගය තුන් වරක් මුද්‍රණය කර ඇති බවයි.

function foo() {
  var result = []
  for (var i = 0; i < 3; i++) {
    result.push(function inner() { console.log(i) } )
  }
  return result
}

const result = foo()
// The following will print `3`, three times...
for (var i = 0; i < 3; i++) {
  result[i]() 
}

අවසාන ලකුණු:

  • ජාවාස්ක්‍රිප්ට් හි ශ්‍රිතයක් ප්‍රකාශයට පත් කරන සෑම විටම වසා දැමීමක් නිර්මාණය වේ.
  • ආපසු පැමිණීම a functionවෙනත් ශ්‍රිතයක් ඇතුළත සිට වසා දැමීමේ සම්භාව්‍ය නිදසුනකි, මන්ද පිටත ශ්‍රිතය ක්‍රියාත්මක වීමෙන් පසුව වුවද පිටත ශ්‍රිතය තුළ ඇති තත්වය ආපසු එන අභ්‍යන්තර ශ්‍රිතයට ව්‍යංගයෙන් ලබා ගත හැකිය.
  • ඔබ eval()ශ්‍රිතයක් තුළ භාවිතා කරන සෑම විටම වසා දැමීමක් භාවිතා කරයි. පා evalfunction ය මඟින් ඔබට ශ්‍රිතයේ දේශීය විචල්‍යයන් සඳහන් කළ හැකි අතර, දැඩි නොවන ආකාරයෙන් ඔබට භාවිතා කිරීමෙන් නව දේශීය විචල්‍යයන් පවා නිර්මාණය කළ හැකියeval('var foo = …') .
  • ඔබ ශ්‍රිතයක් තුළ new Function(…)( ක්‍රියාකාරී ඉදිකිරීම්කරු ) භාවිතා කරන විට , එය එහි ශබ්දකෝෂ පරිසරයට වඩා වැසෙන්නේ නැත: එය ගෝලීය සන්දර්භය පුරා වසා දමයි. නව ශ්‍රිතයට බාහිර ශ්‍රිතයේ දේශීය විචල්‍යයන් සඳහන් කළ නොහැක.
  • ජාවාස්ක්‍රිප්ට් වසා දැමීම හරියට යොමු කිරීමක් තබා ගැනීම හා සමානයි ( NOT ක්‍රියාකාරී ප්‍රකාශනයේ දී විෂය පථයට පිටපතක් ) තබා ගැනීම හා සමාන වන අතර එමඟින් එහි බාහිර විෂය පථය වෙත යොමු කිරීමක් තබා ඇති අතර යනාදිය ගෝලීය වස්තුවට ඉහළින් ඇති විෂය පථය.
  • ශ්‍රිතයක් ප්‍රකාශයට පත් කළ විට වසා දැමීමක් නිර්මාණය වේ; ශ්‍රිතය ක්‍රියාත්මක වන විට ක්‍රියාත්මක කිරීමේ සන්දර්භය වින්‍යාස කිරීමට මෙම වසා දැමීම භාවිතා කරයි.
  • ශ්‍රිතයක් හැඳින්වෙන සෑම අවස්ථාවකම නව දේශීය විචල්‍යයන් සමූහයක් නිර්මාණය වේ.

සබැඳි


74
මෙය කදිමයි: "ජාවාස්ක්‍රිප්ට් හි වසා දැමීමක් යනු සියලුම දේශීය විචල්‍යයන්ගේ පිටපතක් තබා ගැනීම හා සමානයි. නමුත් එය හේතු කිහිපයක් නිසා නොමඟ යවන සුළුය. (1) වසා දැමීමක් නිර්මාණය කිරීම සඳහා ශ්‍රිත ඇමතුමෙන් පිටවිය යුතු නැත. (2) එය දේශීය විචල්‍යයන්ගේ අගයන්හි පිටපතක් නොව විචල්‍යයන්ම වේ. (3) මෙම විචල්‍යයන්ට ප්‍රවේශය ඇත්තේ කාටදැයි එහි සඳහන් නොවේ.
dlaliberte

27
උදාහරණ 5 හි දැක්වෙන්නේ කේතය අපේක්ෂිත පරිදි ක්‍රියා නොකරන "ගොචා" ය. නමුත් එය නිවැරදි කරන්නේ කෙසේදැයි පෙන්වන්නේ නැත. මෙම අනෙක් පිළිතුර එය කිරීමට ක්‍රමයක් පෙන්වයි.
මැට්

190
මෙම පෝස්ට් "තද වැසුම් මැජික් නොවේ" යැයි කියමින් තද අකුරින් ආරම්භ වන ආකාරය සහ එහි පළමු උදාහරණය "මැජික් යනු ජාවාස්ක්‍රිප්ට් හි ක්‍රියාකාරී යොමු කිරීමක් තුළ එය නිර්මාණය කරන ලද වසා දැමීම පිළිබඳ රහසිගත සඳහනක් ඇත" යන්න අවසන් කිරීමට මම කැමතියි.
ඇන්ඩ rew මැකරෙට්

6
උදාහරණ # 3 යනු ජාවාස්ක්‍රිප්ට් එසවීම සමඟ වසා දැමීම් මිශ්‍ර කිරීමයි. දැන් මම හිතන්නේ එසවීමේ හැසිරීම ගෙන ඒමෙන් තොරව වසා දැමීම් පමණක් පැහැදිලි කිරීම ප්‍රමාණවත් නොවේ. : මේක මට බොහෝ උදව් Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure 'remembers' the environment in which it was created.සිට developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
caramba

3
ECMAScript 6 වසා දැමීම පිළිබඳ මෙම ශ්‍රේෂ් article ලිපියේ යමක් වෙනස් කළ හැකිය. උදාහරණයක් ලෙස, ඔබ උදාහරණ 5 let i = 0වෙනුවට භාවිතා කරන්නේ නම් var i = 0, එවිට testList()ඔබට අවශ්‍ය දේ මුලින් මුද්‍රණය කෙරේ.
නියර්

3989

ජාවාස්ක්‍රිප්ට් හි සෑම ශ්‍රිතයක්ම එහි බාහිර ශබ්දකෝෂ පරිසරයට සම්බන්ධයක් පවත්වා ගනී. ශබ්දකෝෂ පරිසරයක් යනු විෂය පථයක් තුළ ඇති සියළුම නම්වල (උදා.

එබැවින්, ඔබ functionමූල පදය දකින සෑම විටම , එම ශ්‍රිතය තුළ ඇති කේතයට ශ්‍රිතයෙන් පිටත ප්‍රකාශිත විචල්‍යයන්ට ප්‍රවේශය ඇත.

function foo(x) {
  var tmp = 3;

  function bar(y) {
    console.log(x + y + (++tmp)); // will log 16
  }

  bar(10);
}

foo(2);

පරාමිතිය හා විචල්‍යය හරහා 16ශ්‍රිතය barවැසෙන බැවින් මෙය ලොග් වනු ඇත , මේ දෙකම පිටත ශ්‍රිතයේ ශබ්දකෝෂ පරිසරයේ පවතීxtmpfoo .

ශ්‍රිතය bar, ක්‍රියාකාරීත්වයේ ශබ්දකෝෂ පරිසරය සමඟ එහි සම්බන්ධතාවය fooවසා දැමීමකි.

වසා දැමීමක් නිර්මාණය කිරීම සඳහා ශ්‍රිතයකට ආපසු යා යුතු නැත . හුදෙක් එහි ප්‍රකාශය අනුව, සෑම ශ්‍රිතයක්ම එහි ඇති ශබ්දකෝෂ පරිසරය පුරා වැසෙන අතර එය වසා දැමීමකි.

function foo(x) {
  var tmp = 3;

  return function (y) {
    console.log(x + y + (++tmp)); // will also log 16
  }
}

var bar = foo(2);
bar(10); // 16
bar(10); // 17

ඉහත ශ්‍රිතය 16 ට ලොග් වනු ඇත, මන්ද ඇතුළත කේතය තවදුරටත් සෘජුවම විෂය පථයට නොතිබුණද, barතර්කය xසහ විචල්‍යය වෙත යොමු විය හැකිය tmp.

කෙසේ වෙතත්, tmpතවමත් barවසා දැමීම ඇතුළත එල්ලී ඇති බැවින් , එය වැඩි කිරීමට ලබා ගත හැකිය. ඔබ අමතන සෑම අවස්ථාවකම එය වැඩි වේbar වේ.

වසා දැමීමේ සරලම උදාහරණය මෙයයි:

var a = 10;

function test() {
  console.log(a); // will output 10
  console.log(b); // will output 6
}
var b = 6;
test();

ජාවාස්ක්‍රිප්ට් ශ්‍රිතයක් ක්‍රියාත්මක කළ විට, නව ක්‍රියාත්මක කිරීමේ සන්දර්භයක් ecනිර්මාණය වේ. ක්‍රියාකාරී තර්ක සහ ඉලක්කගත වස්තුව සමඟ එක්ව, මෙම ක්‍රියාත්මක කිරීමේ සන්දර්භය ඇමතුම් ක්‍රියාත්මක කිරීමේ සන්දර්භයේ ශබ්දකෝෂ පරිසරයට සබැඳියක් ලබා ගනී, එයින් අදහස් වන්නේ පිටත ශබ්දකෝෂ පරිසරයේ ප්‍රකාශිත විචල්‍යයන් (ඉහත උදාහරණයේ දී aසහ දෙකම b) ලබා ගත හැකි ecබවයි.

සෑම ශ්‍රිතයක්ම එහි පිටත ශබ්දකෝෂ පරිසරයට සම්බන්ධයක් ඇති නිසා සෑම ශ්‍රිතයක්ම වැසීමක් ඇති කරයි.

විචල්යයන් සටහන තමන් ඉතා වසා දැමීම, ඇතුළත සිට දෘශ්යමාන වේ නොහැකි පිටපත්.


24
@feeela: ඔව්, සෑම JS ශ්‍රිතයක්ම වසා දැමීමක් නිර්මාණය කරයි. නූතන ජේඑස් එන්ජින්වල කසළ එකතු කිරීම සඳහා යොමු නොකෙරෙන විචල්‍යයන් බොහෝ විට සුදුසුකම් ලැබෙනු ඇත, නමුත් ඔබ ක්‍රියාත්මක කිරීමේ සන්දර්භයක් නිර්මාණය කරන විට, එම සන්දර්භය තුළ ක්‍රියාත්මක වන සන්දර්භය සහ එහි විචල්‍යයන් පිළිබඳ සඳහනක් ඇති බව වෙනස් නොවේ. එම ශ්‍රිතය එම මුල් යොමුව රඳවා තබා ගනිමින් වෙනත් විචල්‍ය විෂය පථයකට නැවත ස්ථානගත කළ හැකි වස්තුවකි. එය වසා දැමීමයි.

Li අලි මම සොයාගෙන ඇති jsFiddle ඇත්ත වශයෙන්ම කිසිවක් ඔප්පු නොකරන බව deleteඅසමත් බැවින් . එසේ වුවද, ශ්‍රිතය [[විෂය පථය]] ලෙස ගෙන යන ශබ්දකෝෂ පරිසරය (සහ අවසාන වශයෙන් ආයාචනා කරන විට එය තමන්ගේම ශබ්දකෝෂ පරිසරය සඳහා පදනමක් ලෙස භාවිතා කරයි) තීරණය කරනුයේ ශ්‍රිතය අර්ථ දක්වන ප්‍රකාශය ක්‍රියාත්මක වන විට ය. මෙම උත්සවයට එහි අර්ථය වන්නේ නොතකා එය සැබවින්ම කර ගැනීමට හා එය විෂය පථය ගැළවෙන යන්න සඳහන් අගය වන, ක්රියාත්මක කිරීමේ විෂය පථය සමස්ත අන්තර්ගතයට වඩා වසා. කරුණාකර පිරිවිතරයේ
අසාද් සයීදුදින්

8
ප්‍රාථමික වර්ග සහ යොමු කිරීම් පැහැදිලි කිරීමට උත්සාහ කරන තෙක් මෙය හොඳ පිළිතුරකි. එය සම්පූර්ණයෙන්ම වැරදියි සහ වචනානුසාරයෙන් පිටපත් කිරීම ගැන කථා කරයි, එය ඇත්ත වශයෙන්ම කිසිවක් සමඟ කිසිදු සම්බන්ධයක් නැත.
රයි-

12
වසා දැමීම් යනු පංති පාදක, වස්තු නැඹුරු වැඩසටහන්කරණයට ජාවාස්ක්‍රිප්ට්ගේ පිළිතුරයි. JS යනු පන්ති පදනම් නොවන බැවින් වෙනත් ආකාරයකින් ක්‍රියාත්මක කළ නොහැකි සමහර දේවල් ක්‍රියාත්මක කිරීමට කෙනෙකුට වෙනත් ක්‍රමයක් සොයා ගැනීමට සිදු විය.
බාර්ටෝමිජ් සාලෙව්ස්කි

2
මෙය පිළිගත් පිළිතුර විය යුතුය. මැජික් කිසි විටෙකත් අභ්‍යන්තර ක්‍රියාකාරිත්වයේ සිදු නොවේ. පිටත ශ්‍රිතය විචල්‍යයකට පැවරූ විට එය සිදු වේ. මෙය අභ්‍යන්තර ශ්‍රිතය සඳහා නව ක්‍රියාත්මක කිරීමේ සන්දර්භයක් නිර්මාණය කරයි, එබැවින් "පුද්ගලික විචල්‍යය" රැස් කර ගත හැකිය. ඇත්ත වශයෙන්ම එයට විචල්‍යයෙන් පවරා ඇති බාහිර ශ්‍රිතය සන්දර්භය පවත්වා ගෙන යා හැකිය. පළමු පිළිතුර එහි ඇත්ත වශයෙන්ම සිදුවන්නේ කුමක්ද යන්න පැහැදිලි නොකර මුළු දේම වඩාත් සංකීර්ණ කරයි.
ඇල්බට් ගාඕ

2442

FOREWORD: මෙම පිළිතුර ලියා ඇත්තේ ප්‍රශ්නය:

පැරණි ඇල්බට් පැවසූ පරිදි: "ඔබට එය හය හැවිරිදි දරුවෙකුට පැහැදිලි කළ නොහැකි නම්, ඔබට එය ඔබම වටහා ගත නොහැක." හොඳයි, මම ජේඑස් වසා දැමීම් 27 හැවිරිදි මිතුරෙකුට පැහැදිලි කිරීමට උත්සාහ කළ අතර එය සම්පූර්ණයෙන්ම අසාර්ථක විය.

මගේ වයස අවුරුදු 6 ක් බවත් එම විෂය ගැන අමුතු උනන්දුවක් දක්වන බවත් කිසිවෙකුට සලකා බැලිය හැකිද?

ආරම්භක ප්‍රශ්නය වචනාර්ථයෙන් ගැනීමට උත්සාහ කළ එකම පුද්ගලයා මම බව මට හොඳටම විශ්වාසයි. එතැන් සිට, ප්‍රශ්නය කිහිප වතාවක්ම විකෘති වී ඇත, එබැවින් මගේ පිළිතුර දැන් ඇදහිය නොහැකි තරම් මෝඩ සහ පිටතින් පෙනේ. කතාවේ සාමාන්‍ය අදහස සමහරුන්ට විනෝදයක් වනු ඇතැයි අපේක්‍ෂා කරමු.


අසීරු සංකල්ප පැහැදිලි කිරීමේදී මම ප්‍රතිසම හා රූපකයේ විශාල රසිකයෙක්, එබැවින් මට කතාවක් සමඟ මගේ අත උත්සාහ කිරීමට ඉඩ දෙන්න.

එකෝමත් එක කාලෙක:

කුමරියක සිටියා ...

function princess() {

ඇය ජීවත් වූයේ වික්‍රමාන්විතයන්ගෙන් පිරුණු අපූරු ලෝකයක ය. ඇයට චාමින් කුමරු මුණ ගැසුණි, යුනිකෝනයක නැගී, මකරුන් සමඟ සටන් කළාය, කතා කරන සතුන් හමු විය, සහ තවත් බොහෝ මන fant කල්පිත දේ.

    var adventures = [];

    function princeCharming() { /* ... */ }

    var unicorn = { /* ... */ },
        dragons = [ /* ... */ ],
        squirrel = "Hello!";

    /* ... */

නමුත් ඇයට සෑම විටම ඇගේ අඳුරු වැඩ සහ වැඩිහිටියන්ගේ ලෝකයට ආපසු යාමට සිදුවනු ඇත.

    return {

කුමරියක ලෙස ඇයගේ නවතම විස්මිත වික්‍රමය ගැන ඇය බොහෝ විට ඔවුන්ට පවසනු ඇත.

        story: function() {
            return adventures[adventures.length - 1];
        }
    };
}

නමුත් ඔවුන් දකින්නේ කුඩා දැරියක් පමණයි ...

var littleGirl = princess();

... මැජික් සහ ෆැන්ටසි ගැන කතන්දර කියන්න.

littleGirl.story();

වැඩිහිටියන් සැබෑ කුමාරිකාවන් ගැන දැන සිටියත්, ඔවුන් කිසි විටෙකත් යුනිකෝන් හෝ මකරුන් විශ්වාස නොකරනු ඇත. වැඩිහිටියන් පැවසුවේ ඔවුන් සිටියේ කුඩා දැරියගේ පරිකල්පනය තුළ පමණක් බවයි.

නමුත් සැබෑ සත්‍යය අපි දනිමු. කුමරිය සමඟ සිටින කුඩා දැරිය ...

... ඇත්තටම කුමරියක ඇතුලේ පොඩි කෙල්ලෙක් ඉන්නවා.


340
මම ඇත්ත වශයෙන්ම මෙම පැහැදිලි කිරීමට කැමතියි. එය කියවා අනුගමනය නොකරන අය සඳහා ප්‍රතිසමයක් මෙයයි: කුමරියගේ () ශ්‍රිතය පුද්ගලික දත්ත අඩංගු සංකීර්ණ විෂය පථයකි. ශ්‍රිතයෙන් පිටත, පුද්ගලික දත්ත දැකීමට හෝ ප්‍රවේශ වීමට නොහැක. කුමරිය යුනිකෝන්, මකරුන්, වික්‍රමාන්විතයන් යනාදිය ඇගේ පරිකල්පනය තුළ තබා ගනී (පුද්ගලික දත්ත) සහ වැඩිහිටියන්ට ඒවා තනිවම දැකිය නොහැක. නමුත් කුමරියගේ පරිකල්පනය story()ශ්‍රිතය සඳහා වසා දැමීමේදී ග්‍රහණය කරගනු ලැබේ , එය littleGirlමැජික් ලෝකයට නිරාවරණය වන එකම අතුරු මුහුණත වේ.
පැට්‍රික් එම්

මෙන්න storyවසා දැමීම නමුත් කේතය තිබුනේ var story = function() {}; return story;නම් littleGirlඑය වසා දැමීම වේ. අවම වශයෙන් එය එම්ඩීඑන් විසින් වසා දැමීම් සහිත 'පුද්ගලික' ක්‍රම භාවිතා කිරීමෙන් මට ලැබෙන හැඟීමයි : "එම පොදු කාර්යයන් තුන එකම පරිසරය බෙදා ගන්නා වසා දැමීම් වේ."
icc97

16
@ icc97, ඔව්, storyයනු විෂය පථය තුළ සපයා ඇති පරිසරය සඳහන් කරන වසා දැමීමකි princess. princessතවත් ද ව්යංග වසා දැමීම, එනම්, princessසහ littleGirlඑය කිසිදු සඳහනක් පංගුකාරයන් වනු ඇත parentsඑහිදී පරිසරය / විෂය පථය නැවත ඇති වන බව මාලාවක් littleGirlපවතී හා princessඅර්ථ දක්වා ඇත.
ජේකබ් ස්වාර්ට්වුඩ්

6
En බෙන්ජමින් කෘප් princessලියා ඇති දේට වඩා ශරීරය තුළ වැඩි මෙහෙයුම් ප්‍රමාණයක් ඇති බව පෙන්වීමට / ඇඟවීමට මම පැහැදිලි කේත විවරණයක් එක් කළෙමි . අවාසනාවට මෙම කථාව දැන් මෙම ත්‍රෙඩ් එකෙන් ටිකක් ඉවතට. මුලින් ප්‍රශ්නය වූයේ "ජාවාස්ක්‍රිප්ට් වසා දැමීම් අවුරුදු 5 ක් පැරණි අයට පැහැදිලි කරන්න"; මගේ ප්‍රතිචාරය එය කිරීමට උත්සාහ කළ එකම එකයි. එය අවාසනාවන්ත ලෙස අසාර්ථක වනු ඇතැයි මම සැක නොකරමි, නමුත් අවම වශයෙන් මෙම ප්‍රතිචාරයට අවුරුදු 5 ක පැරණි උනන්දුවක් දැක්වීමට අවස්ථාවක් ලැබෙනු ඇත.
ජේකබ් ස්වාර්ට්වුඩ්

11
ඇත්තටම, මට මෙය පරිපූර්ණ අර්ථයක් ලබා දුන්නා. මම පිළිගත යුතුයි, අවසාන වශයෙන් කුමරියන්ගේ හා වික්‍රමාන්විත කතා භාවිතා කරමින් JS වසා දැමීමක් තේරුම් ගැනීම මට ටිකක් අමුතු හැඟීමක් ඇති කරයි.
Crystallize

753

ප්‍රශ්නය බැරෑරුම් ලෙස සලකන විට, සාමාන්‍ය 6 හැවිරිදි දරුවෙකුට සංජානනීය හැකියාවක් ඇත්තේ කුමක් දැයි අප සොයා ගත යුතුය. එහෙත්, ජාවාස්ක්‍රිප්ට් ගැන උනන්දුවක් දක්වන අයෙකු එතරම් සාමාන්‍ය නොවන බව පිළිගත යුතුය.

මත ළමාවිය සංවර්ධන: 5 සිට 7 දක්වා අවුරුදු කියයි:

ඔබේ දරුවාට පියවර දෙකක උපදෙස් අනුගමනය කළ හැකිය. නිදසුනක් වශයෙන්, ඔබ ඔබේ දරුවාට "කුස්සියට ගොස් මට කුණු මල්ලක් ලබා දෙන්න" යැයි පැවසුවහොත් ඔවුන්ට එම දිශාව මතක තබා ගත හැකිය.

වසා දැමීම් පැහැදිලි කිරීම සඳහා අපට මෙම උදාහරණය භාවිතා කළ හැකිය,

මුළුතැන්ගෙය යනු දේශීය විචල්‍යයක් ඇති වසා දැමීමකි trashBags. මුළුතැන්ගෙය තුළ getTrashBagඑක් කුණු බෑගයක් ලබා ගෙන එය ආපසු ලබා දෙන ශ්‍රිතයක් ඇත .

අපට මෙය JavaScript හි කේත කළ හැකිය:

function makeKitchen() {
  var trashBags = ['A', 'B', 'C']; // only 3 at first

  return {
    getTrashBag: function() {
      return trashBags.pop();
    }
  };
}

var kitchen = makeKitchen();

console.log(kitchen.getTrashBag()); // returns trash bag C
console.log(kitchen.getTrashBag()); // returns trash bag B
console.log(kitchen.getTrashBag()); // returns trash bag A

වසා දැමීම් සිත්ගන්නාසුලු වන්නේ මන්දැයි පැහැදිලි කරන තවත් කරුණු:

  • සෑම වාරයක්ම makeKitchen()හැඳින්වෙන විට, තමන්ගේම වෙනමම නව වසා දැමීමක් නිර්මාණය වේtrashBags .
  • මෙම trashBagsවිචල්ය එක් එක් මුළුතැන්ගෙයි ඇතුළත දේශීය හා ප්රවේශයන් නොවේ, නමුත් මත අභ්යන්තර ශ්රිතයgetTrashBag දේපල ඒ සඳහා ප්රවේශයන් කරන්නේ.
  • සෑම ශ්‍රිත ඇමතුමක්ම වසා දැමීමක් නිර්මාණය කරයි, නමුත් වසා දැමීමේ අභ්‍යන්තරයට ප්‍රවේශය ඇති අභ්‍යන්තර ශ්‍රිතයක් වසා දැමීමෙන් පිටත සිට ඇමතිය නොහැකි නම් වසා දැමීම අවට තබා ගැනීමේ අවශ්‍යතාවයක් නොමැත. getTrashBagශ්‍රිතය සමඟ වස්තුව නැවත ලබා දීම මෙහි සිදු කරයි.

6
ඇත්ත වශයෙන්ම, ව්‍යාකූල ලෙස, makeKitchen ක්‍රියාකාරී ඇමතුම සත්‍ය වසා දැමීම මිස එය නැවත පැමිණෙන මුළුතැන්ගෙයි වස්තුව නොවේ.
dlaliberte

6
අනෙක් අය අතරට යාමෙන් මෙම පිළිතුර වසා දැමීම් මොනවාද සහ ඇයි යන්න පැහැදිලි කිරීමට පහසුම ක්‍රමය ලෙස මම සොයා ගතිමි.
චෙතබාහන

3
ඕනෑවට වඩා මෙනුව සහ ආහාර රුචිය, මස් හා අර්තාපල් ප්‍රමාණවත් නොවේ. ඔබට එම පිළිතුර එක් කෙටි වාක්‍යයකින් වැඩි දියුණු කළ හැකිය: "වසා දැමීම යනු ශ්‍රිතයක මුද්‍රා තැබූ සන්දර්භයයි.
ස්ටැප්ලර්ෆහර්

584

පිදුරු මිනිසා

බොත්තමක් කී වතාවක් ක්ලික් කර ඇත්දැයි දැන ගැනීමට අවශ්‍ය වන අතර සෑම තෙවන ක්ලික් කිරීමකදීම යමක් කරන්න ...

තරමක් පැහැදිලි විසඳුම

// Declare counter outside event handler's scope
var counter = 0;
var element = document.getElementById('button');

element.addEventListener("click", function() {
  // Increment outside counter
  counter++;

  if (counter === 3) {
    // Do something every third time
    console.log("Third time's the charm!");

    // Reset counter
    counter = 0;
  }
});
<button id="button">Click Me!</button>

දැන් මෙය ක්‍රියාත්මක වනු ඇත, නමුත් එය විචල්‍යයක් එකතු කිරීමෙන් පිටත විෂය පථයට ඇතුල් වේ, එහි එකම අරමුණ ගණනය කිරීම් නිරීක්ෂණය කිරීමයි. සමහර අවස්ථාවලදී, ඔබේ බාහිර යෙදුමට මෙම තොරතුරු වෙත ප්‍රවේශය අවශ්‍ය විය හැකි බැවින් මෙය වඩාත් යෝග්‍ය වේ. නමුත් මේ අවස්ථාවේ දී, අපි වෙනස් කරන්නේ සෑම තුන්වන ක්ලික් කිරීමක හැසිරීම පමණි, එබැවින් මෙම ක්‍රියාකාරීත්වය සිදුවීම් හසුරුවන්නා තුළ කොටු කර ගැනීම වඩාත් සුදුසුය .

මෙම විකල්පය සලකා බලන්න

var element = document.getElementById('button');

element.addEventListener("click", (function() {
  // init the count to 0
  var count = 0;

  return function(e) { // <- This function becomes the click handler
    count++; //    and will retain access to the above `count`

    if (count === 3) {
      // Do something every third time
      console.log("Third time's the charm!");

      //Reset counter
      count = 0;
    }
  };
})());
<button id="button">Click Me!</button>

මෙහි කරුණු කිහිපයක් සැලකිල්ලට ගන්න.

ඉහත උදාහරණයේ දී, මම ජාවාස්ක්‍රිප්ට් හි සංවෘත හැසිරීම භාවිතා කරමි. මෙම හැසිරීම මඟින් ඕනෑම කාර්යයකට එය නිර්මාණය කළ විෂය පථයට දින නියමයක් නොමැතිව ප්‍රවේශ වීමට ඉඩ ලබා දේ. මෙය ප්‍රායෝගිකව ක්‍රියාවට නැංවීම සඳහා, මම වහාම වෙනත් ශ්‍රිතයක් ලබා දෙන ශ්‍රිතයක් ඉල්ලා සිටින අතර, මා නැවත පැමිණෙන ශ්‍රිතයට අභ්‍යන්තර ගණන් විචල්‍යයට ප්‍රවේශය ඇති හෙයින් (ඉහත විස්තර කර ඇති සංවෘත හැසිරීම නිසා) මෙහි ප්‍රති results ලයක් ලෙස භාවිතය සඳහා පුද්ගලික විෂය පථයක් ලැබේ. ක්‍රියාකාරිත්වය ... එතරම් සරල නොවේ ද? අපි එය තනුක කරමු ...

සරල එක් පේළියක් වසා දැමීම

//          _______________________Immediately invoked______________________
//         |                                                                |
//         |        Scope retained for use      ___Returned as the____      |
//         |       only by returned function   |    value of func     |     |
//         |             |            |        |                      |     |
//         v             v            v        v                      v     v
var func = (function() { var a = 'val'; return function() { alert(a); }; })();

ආපසු ලබා දුන් ශ්‍රිතයට පිටතින් ඇති සියලුම විචල්‍යයන් ආපසු ලබා දුන් ශ්‍රිතයට ලබා ගත හැකිය, නමුත් ඒවා ආපසු ලබා දුන් ශ්‍රිත වස්තුවට කෙලින්ම ලබාගත නොහැක ...

func();  // Alerts "val"
func.a;  // Undefined

එය ලබා ගන්න? එබැවින් අපගේ ප්‍රාථමික උදාහරණයේ දී, ගණන් කිරීමේ විචල්‍යය වසා දැමීම තුළ අඩංගු වන අතර එය සැමවිටම සිදුවීම් හසුරුවන්නාට ලබා ගත හැකිය, එබැවින් එය ක්ලික් සිට ක්ලික් කිරීම දක්වා එහි තත්වය රඳවා ගනී.

එසේම, මෙම පුද්ගලික විචල්‍ය තත්වයට කියවීම සහ එහි පුද්ගලික විෂය පථ විචල්‍යයන් සඳහා සම්පූර්ණයෙන්ම ප්‍රවේශ විය හැකිය.

ඔන්න ඔයා යන්න; ඔබ දැන් මෙම හැසිරීම සම්පූර්ණයෙන්ම වටහාගෙන ඇත.

සම්පුර්ණ බ්ලොග් සටහන (jQuery සලකා බැලීම් ඇතුළුව)


11
වසා දැමීම යනු කුමක්ද යන්න පිළිබඳ ඔබේ අර්ථ දැක්වීම සමඟ මම එකඟ නොවෙමි. එය ස්වයං ආයාචනා කිරීමට හේතුවක් නැත. එය "ආපසු" ලබා දිය යුතු යැයි පැවසීමද තරමක් සරල (සහ සාවද්‍ය) (මෙම ප්‍රශ්නයට ඉහළම පිළිතුරේ අදහස් දැක්වීමේදී මේ පිළිබඳව බොහෝ සාකච්ඡා)
ජේම්ස් මොන්ටැග්න්

40
Ames ජේම්ස් ඔබ කැමති නොවුනත්, ඔහුගේ ආදර්ශය (සහ සම්පූර්ණ තනතුරම) මා දුටු හොඳම එකකි. ප්‍රශ්නය පරණ නොවන අතර මට එය විසඳා ඇතත්, එය මුළුමනින්ම +1 ලැබීමට සුදුසුය.
ඊ-තෘප්තිමත්

84
"බොත්තමක් කී වතාවක් ක්ලික් කර ඇත්දැයි දැන ගැනීමට මට අවශ්‍යය. සෑම තෙවන ක්ලික් කිරීමකදීම යමක් කරන්න ..." මෙය මගේ අවධානයට ලක්විය. වසා දැමීම එතරම් අද්භූත දෙයක් නොවන බවත්, අපෙන් බොහෝ දෙනෙක් ඒවා ලියන නමුත් නිල නාමය හරියටම නොදැන සිටි බවත් පෙන්වන භාවිත නඩුවක් සහ විසඳුම.
ක්‍රිස් 22

2 වන උදාහරණයේ “ගණන් කිරීම” “ගණන්” වල අගය රඳවාගෙන ඇති බවත් “මූලද්‍රව්‍යය” ක්ලික් කළ සෑම අවස්ථාවකම 0 ට නැවත සකසන්නේ නැති බවත් පෙන්වන හොඳ උදාහරණයකි. ඉතා තොරතුරු!
ඇඩම්

වසා දැමීමේ හැසිරීම සඳහා +1 . අපි සීමා කිරීමට හැක වසා හැසිරීම කිරීමට කටයුතු ජාවාස්ක්රිප්ට් හෝ මෙම සංකල්පය භාෂාව අනෙකුත් ඉදිකිරීම් සඳහා ද යෙදිය හැකි?
ඩියාමිඩ්

493

වසා දැමීම් පැහැදිලි කිරීම අසීරු වන්නේ ඒවා කෙසේ හෝ වැඩ කිරීමට සෑම කෙනෙක්ම බුද්ධිමත්ව අපේක්ෂා කරන යම් හැසිරීමක් වැඩ කිරීමට භාවිතා කරන බැවිනි. ඒවා පැහැදිලි කිරීමට හොඳම ක්‍රමය මම සොයා ගතිමි (සහ ඔවුන් කරන දේ මම ඉගෙන ගත් ආකාරය) ඔවුන් නොමැතිව තත්වය මවා ගැනීම:

    var bind = function(x) {
        return function(y) { return x + y; };
    }
    
    var plus5 = bind(5);
    console.log(plus5(3));

ජාවාස්ක්‍රිප්ට් වසා දැමීම් නොදැන සිටියේ නම් මෙහි කුමක් සිදුවේද? අන්තිම පේළියේ ඇති ඇමතුම එහි ක්‍රමවේදය මඟින් ප්‍රතිස්ථාපනය කරන්න (එය මූලික වශයෙන් ක්‍රියාකාරී ඇමතුම් කරන්නේ) සහ ඔබට ලැබෙන්නේ:

console.log(x + 3);

දැන්, අර්ථ දැක්වීම කොහිද x? වර්තමාන විෂය පථය තුළ අපි එය අර්ථ දක්වා නැත. එකම විසඳුම වන්නේ එහි විෂය පථය (හෝ ඒ වෙනුවට, දෙමව්පියන්ගේ විෂය පථය) plus5 ගෙනයාමට ඉඩ දීමයි . මේ ආකාරයෙන්, xමනාව නිර්වචනය කර ඇති අතර එය 5 අගයට බැඳී ඇත.


11
මෙය හරියටම බොහෝ දෙනා නොමඟ යවන උදාහරණයකි, එය ආපසු ලබා දුන් ශ්‍රිතයේ භාවිතා වන අගයන් මිස වෙනස් කළ හැකි විචල්‍යය නොවේ. එය "ආපසු x + = y" ලෙස වෙනස් කර ඇත්නම් හෝ ඊට වඩා හොඳ සහ "x * = y" යන ශ්‍රිතය යන දෙකම වෙනස් කර ඇත්නම්, කිසිවක් පිටපත් නොකරන බව පැහැදිලිය. රාමු ගොඩගැසීමට භාවිතා කරන පුද්ගලයින් සඳහා, ඒ වෙනුවට ගොඩවල් රාමු භාවිතා කිරීම ගැන සිතා බලන්න, එය ශ්‍රිතය නැවත පැමිණීමෙන් පසුවද පැවතිය හැකිය.
මැට්

14
Att මාට් එකඟ නොවෙමි. උදාහරණයක් වේ නොහැකි , දීර්ඝ වශයෙන් සියලු ගුණ ලේඛනගත කිරීමට නියමිත. එය අඩුකිරීමට අදහස් කරන අතර සංකල්පයක වැදගත් ලක්ෂණය විදහා දක්වයි. OP සරල පැහැදිලි කිරීමක් ඉල්ලා සිටියේය (“හය හැවිරිදි දරුවෙකු සඳහා”). පිළිගත් පිළිතුර ගන්න: සංක්ෂිප්ත පැහැදිලි කිරීමක් කිරීමට එය මුළුමනින්ම අසමත් වන්නේ හරියටම එය පරිපූර්ණ වීමට උත්සාහ කරන බැවිනි. (මම එය බන්ධන වඩා යොමු විසින් අගය විසින් බව ... නමුත් නැවත, සාර්ථක පැහැදිලි කිරීමක් ඉතාමත් අවම කිරීමට අඩු බව එක් JavaScript වැදගත් දේපලක් බව ඔබ සමඟ එකඟ නැහැ.)
කොන්රාඩ් රුඩොල්ෆ්

On කොන්රාඩ් රුඩොල්ෆ් මම කැමතියි ඔබේ ආදර්ශයේ ශෛලිය හා සාරාංශය. "එකම විසඳුම ..." යන අවසාන කොටස සත්‍ය බවට පත්වන පරිදි එය තරමක් වෙනස් කිරීමට මම නිර්දේශ කරමි. දැනට නැත ඔබේ තත්වය තවත්, සරල විසඳුමක්, ඇත්ත ඇති නොවන ජාවාස්ක්රිප්ට් continuations අනුරූප, හා කරන්නේ continuations දේ පිළිබඳ පොදු වැරදි සංකල්පයක් අනුරූප. මේ අනුව එහි වර්තමාන ස්වරූපයෙන් ඇති උදාහරණය භයානක ය. මෙය පරිපූර්ණ ලෙස ලැයිස්තුගත කිරීමේ ගුණාංග සමඟ සම්බන්ධ නොවිය යුතුය, එය ආපසු හරවන ලද ශ්‍රිතයේ x යනු කුමක්ද යන්න තේරුම් ගැනීම සමඟ කළ යුතුය.
මැට්

Att මැට් හ්ම්, මම ඔබව සම්පූර්ණයෙන් තේරුම් ගෙන ඇති බව මට විශ්වාස නැත, නමුත් ඔබට වලංගු කරුණක් ඇති බව මම දකිමි. අදහස් ඉතා කෙටි බැවින්, සාරාංශයක් / පැස්ටියක් හෝ චැට් රූම් එකක ඔබ අදහස් කරන දේ ඔබට පැහැදිලි කළ හැකිද? ස්තූතියි.
කොන්රාඩ් රුඩොල්ෆ්

2
On කොන්රාඩ් රුඩොල්ෆ් x + = y හි අරමුණ ගැන මට පැහැදිලි නැතැයි මම සිතමි. මෙහි අරමුණ වූයේ ආපසු හරවන ලද ශ්‍රිතයට නැවත නැවත ඇමතුම් එකම විචල්‍ය x භාවිතා කරන බව පෙන්වීම පමණි (එම අගයම ප්‍රතිවිරුද්ධව , ශ්‍රිතය නිර්මාණය කරන විට "ඇතුල් කරනු ලැබේ" යැයි මිනිසුන් සිතන). මෙය ඔබේ ෆෙඩෙල්හි පළමු ඇඟවීම් දෙක හා සමානයි. X * = y අතිරේක ශ්‍රිතයක පරමාර්ථය වනුයේ ආපසු හරවන ලද ශ්‍රිත සියල්ලම එකම x බෙදා ගන්නා බව පෙන්වීමයි.
මැට්

379

ටීඑල්ඩීආර්

වසා දැමීම යනු ශ්‍රිතයක් සහ එහි බාහිර ශබ්දකෝෂ (එනම් ලිඛිත) පරිසරය අතර සම්බන්ධයකි, එනම් එම පරිසරය තුළ අර්ථ දක්වා ඇති හඳුනාගැනීම් (විචල්‍යයන්, පරාමිතීන්, ශ්‍රිත ප්‍රකාශන යනාදිය) ශ්‍රිතය තුළ සිට දෘශ්‍යමාන වේ. ශ්‍රිතය ආයාචනා කරන තැන.

විස්තර

ECMAScript පිරිවිතරයේ පාරිභාෂිතය තුළ, [[Environment]]සෑම ශ්‍රිත වස්තුවක්ම යොමු කිරීමෙන් වසා දැමීමක් ක්‍රියාත්මක කළ හැකි යැයි පැවසිය හැකිය , එමඟින් ශ්‍රිතය අර්ථ දක්වා ඇති ශබ්දකෝෂ පරිසරය වෙත යොමු වේ.

උත්සවයකට අභ්යන්තර හරහා පළ කළහ විට [[Call]]ක්රමය අනුව [[Environment]]මෙම උත්සවයට-වස්තුවක් මත සඳහන විනිවිදකය පිටපත් පිටත පරිසරය යොමු කිරීම පරිසරය වාර්තා විසින් අළුතින් ආරම්භ කරන ලද ක ක්රියාත්මක සන්දර්භය (අඩුක්කුව රාමුව).

පහත දැක්වෙන උදාහරණයේ දී, fගෝලීය ක්‍රියාත්මක කිරීමේ සන්දර්භයේ ශබ්දකෝෂ පරිසරය මත ශ්‍රිතය වැසෙයි:

function f() {}

පහත දැක්වෙන උදාහරණයේ දී, ශ්‍රිතය ශ්‍රිතයේ hශබ්දකෝෂ පරිසරය හරහා වැසෙන අතර g, එමඟින් ගෝලීය ක්‍රියාත්මක කිරීමේ සන්දර්භයේ ශබ්දකෝෂ පරිසරය වසා දමයි.

function g() {
    function h() {}
}

අභ්‍යන්තර ශ්‍රිතයක් පිටතින් නැවත ලබා දෙන්නේ නම්, පිටත ශ්‍රිතය නැවත පැමිණීමෙන් පසු පිටත ශබ්දකෝෂ පරිසරය පවතිනු ඇත. මෙයට හේතුව අභ්‍යන්තර ශ්‍රිතය අවසානයේදී ක්‍රියාත්මක වන්නේ නම් බාහිර ශබ්දකෝෂ පරිසරය තිබිය යුතුය.

පහත දැක්වෙන උදාහරණයේ දී, ශ්‍රිතය ශ්‍රිතයේ jශබ්දකෝෂ පරිසරය හරහා වැසෙයි i, එයින් අදහස් xවන්නේ ශ්‍රිතය ක්‍රියාත්මක jවීමෙන් බොහෝ කලකට පසු අභ්‍යන්තර ශ්‍රිතයෙන් විචල්‍යය දැකිය හැකි බවයි i:

function i() {
    var x = 'mochacchino'
    return function j() {
        console.log('Printing the value of x, from within function j: ', x)
    }
} 

const k = i()
setTimeout(k, 500) // invoke k (which is j) after 500ms

එය වසා, පිටත lexical පරාසය පරිසරය තුළ විචල්යයන් තමන් ලබා ගත හැකි, වන නොවේ පිටපත්.

function l() {
  var y = 'vanilla';

  return {
    setY: function(value) {
      y = value;
    },
    logY: function(value) {
      console.log('The value of y is: ', y);
    }
  }
}

const o = l()
o.logY() // The value of y is: vanilla
o.setY('chocolate')
o.logY() // The value of y is: chocolate

බාහිර පරිසර යොමු කිරීම් හරහා ක්‍රියාත්මක කිරීමේ සන්දර්භයන් අතර සම්බන්ධිත ශබ්දකෝෂ පරිසර දාමය විෂය පථ දාමයක් සාදන අතර ඕනෑම ශ්‍රිතයකින් පෙනෙන හඳුනාගැනීම් අර්ථ දක්වයි.

පැහැදිලිකම සහ නිරවද්‍යතාවය වැඩි දියුණු කිරීමේ උත්සාහයක දී මෙම පිළිතුර මුල් පිටපතෙන් සැලකිය යුතු ලෙස වෙනස් කර ඇති බව කරුණාවෙන් සලකන්න.


56
ඇවැත්නි, ඔබට ඒ වෙනුවට නූල් ආදේශක භාවිතා කළ හැකි බව දැන සිටියේ නැත console.log. වෙනත් අයෙකු උනන්දුවක් දක්වන්නේ නම් තවත් බොහෝ දේ ඇත: developper.mozilla.org/en-US/docs/DOM/…
Flash

7
ශ්‍රිතයේ පරාමිති ලැයිස්තුවේ ඇති විචල්‍යයන් ද වසා දැමීමේ කොටසකි (උදා: ඒවාට පමණක් සීමා නොවේ var).
තෝමස් එඩිං

වසා දැමීම් වස්තූන් හා පංති වැනි ය. බොහෝ අය මේ දෙක සංසන්දනය නොකරන්නේ මන්දැයි නිශ්චිතවම කිව නොහැක - නවක වදය ඉගෙන ගැනීමට අපට පහසු වනු ඇත!
අල්මරුෆ්

377

හරි, අවුරුදු 6 ක් වයසැති වසා දැමීමේ රසිකයෙක්. වසා දැමීමේ සරලම උදාහරණය ඔබට ඇසීමට අවශ්‍යද?

ඊළඟ තත්වය ගැන සිතමු: රියදුරෙක් මෝටර් රථයක වාඩි වී සිටී. ඒ කාර් එක තියෙන්නේ ගුවන් යානයක. ගුවන් යානය ගුවන්තොටුපලේ ඇත. රියදුරුට තම මෝටර් රථයෙන් පිටත දේවල් වෙත ප්‍රවේශ වීමේ හැකියාව, නමුත් යානය ඇතුළත, එම ගුවන් යානය ගුවන් තොටුපලකින් පිටව ගියත්, එය වසා දැමීමකි. ඒක තමයි. ඔබට 27 වන විට, වඩාත් සවිස්තරාත්මක පැහැදිලි කිරීම හෝ පහත උදාහරණය බලන්න.

මෙන්න මගේ ගුවන් කතාව කේතය බවට පරිවර්තනය කළ හැකි ආකාරය.

var plane = function(defaultAirport) {

  var lastAirportLeft = defaultAirport;

  var car = {
    driver: {
      startAccessPlaneInfo: function() {
        setInterval(function() {
          console.log("Last airport was " + lastAirportLeft);
        }, 2000);
      }
    }
  };
  car.driver.startAccessPlaneInfo();

  return {
    leaveTheAirport: function(airPortName) {
      lastAirportLeft = airPortName;
    }
  }
}("Boryspil International Airport");

plane.leaveTheAirport("John F. Kennedy");


26
හොඳින් වාදනය කර මුල් පෝස්ටරයට පිළිතුරු සපයයි. මම හිතන්නේ මෙය හොඳම පිළිතුරයි. මම ගමන් මලු ඒ හා සමාන ආකාරයකින් භාවිතා කිරීමට ගියෙමි: ඔබ ආච්චිගේ නිවසට ගොස් ඔබේ නින්ටෙන්ඩෝ ඩීඑස් නඩුව ඔබේ නඩුව තුළ ක්‍රීඩා කාඩ්පත් සමඟ ඇසුරුම් කර, නමුත් නඩුව ඔබේ බෑගයේ ඇසුරුම් කර ක්‍රීඩා කාඩ්පත් ඔබේ බෑගයේ සාක්කුවල දමා, සහ ඔබ සූට්කේස් සාක්කුවේ වැඩිපුර ක්‍රීඩා කාඩ්පත් සහිත විශාල සූට්කේස් එකක තැබූ විට. ඔබ ආච්චිගේ නිවසට ගිය විට, පිටත ඇති සියලුම සිද්ධීන් විවෘතව පවතින තාක් කල් ඔබට ඕනෑම ක්‍රීඩාවක් ඔබගේ DS හි ක්‍රීඩා කළ හැකිය. හෝ ඒ සඳහා යමක්.
slartibartfast

366

මෙය වෙනත් සමහර පිළිතුරු වල පෙනෙන වසා දැමීම් පිළිබඳ වැරදි වැටහීම් කිහිපයක් ඉවත් කිරීමට ගත් උත්සාහයකි.

  • වසා දැමීමක් නිර්මාණය වන්නේ ඔබ අභ්‍යන්තර ශ්‍රිතයක් නැවත ලබා දෙන විට පමණක් නොවේ. ඇත්ත වශයෙන්ම, සංවෘත ශ්‍රිතය එහි වසා දැමීම නිර්මාණය කිරීම සඳහා කිසිසේත් ආපසු යාමට අවශ්‍ය නොවේ . ඔබට ඒ වෙනුවට ඔබේ අභ්‍යන්තර ශ්‍රිතය බාහිර විෂය පථයක විචල්‍යයකට පැවරිය හැකිය, නැතහොත් එය වෙනත් ශ්‍රිතයකට තර්කයක් ලෙස එය වහාම හෝ පසුව ඕනෑම වේලාවක කැඳවිය හැකිය. එමනිසා, සංවෘත ශ්‍රිතය නැවත කැඳවීමට පෙර හෝ පසුව අභ්‍යන්තර ශ්‍රිතය කැඳවන සෑම අවස්ථාවකම එම වසා දැමීම සඳහා ඕනෑම අභ්‍යන්තර ශ්‍රිතයකට ප්‍රවේශය ඇති බැවින්, සංවෘත ශ්‍රිතය හැඳින්වූ විගසම සංවෘත ශ්‍රිතය වැසී යයි.
  • වසා දැමීමක් එහි විෂය පථයේ විචල්‍යයන්ගේ පැරණි අගයන්ගේ පිටපතක් සඳහන් නොකරයි . විචල්යයන්ම වසා දැමීමේ කොටසක් වන අතර එම නිසා එම විචල්යයන්ගෙන් එකකට ප්රවේශ වන විට පෙනෙන අගය එය ප්රවේශ වන මොහොතේ නවතම අගය වේ. ශ්‍රිතය නිර්මාණය කරන විට හෝ කැඳවන අවස්ථාවේදී විචල්‍යයන්ගේ පිටපතක් උදුරා ගැනීමට වඩා සෑම කෙනෙකුටම එකම බාහිර විචල්‍යයන්ට ප්‍රවේශය ඇති බැවින්, ලූප ඇතුළත නිර්මාණය කරන ලද අභ්‍යන්තර ශ්‍රිත උපක්‍රමශීලී වන්නේ මේ නිසා ය.
  • වසා දැමීමේ "විචල්‍යයන්" තුළ ශ්‍රිතය තුළ ප්‍රකාශිත නම් කරන ලද ශ්‍රිත ඇතුළත් වේ. ඒවාට ශ්‍රිතයේ තර්ක ද ඇතුළත් ය. වසා දැමීමකට ගෝලීය විෂය පථය දක්වාම එහි අඩංගු සංවෘත විචල්‍යයන් වෙත ප්‍රවේශය ඇත.
  • වසා දැමීම් මතකය භාවිතා කරයි, නමුත් ජාවාස්ක්‍රිප්ට් විසින්ම යොමු නොකෙරෙන තමන්ගේම රවුම් ව්‍යුහයන් පිරිසිදු කරන බැවින් ඒවා මතක කාන්දු වීමට හේතු නොවේ. වසා දැමීම් සම්බන්ධ වන ඉන්ටර්නෙට් එක්ස්ප්ලෝරර් මතක කාන්දුවීම් නිර්මාණය වන්නේ එය වසා දැමීම් යොමු කරන DOM ආරෝපණ අගයන් විසන්ධි කිරීමට අපොහොසත් වූ විට ය.

15
ජේම්ස්, මම කිව්වේ වසා දැමීම “බොහෝ විට” නිර්මාණය කර ඇත්තේ සංවෘත ශ්‍රිතය කැඳවන අවස්ථාවේ දී බැවින් එය ක්‍රියාවට නැංවීම මඟින් යම්කිසි කාලයකට පසුව, වසා දැමීමක් අත්‍යවශ්‍ය බව තීරණය කරන තෙක් වසා දැමීමක් නිර්මාණය කිරීම කල් දැමිය හැකි බව පිළිගත හැකි බැවිනි. සංවෘත ශ්‍රිතයේ අභ්‍යන්තර ශ්‍රිතයක් අර්ථ දක්වා නොමැති නම්, වසා දැමීමක් අවශ්‍ය නොවේ. එමනිසා, පළමු අභ්‍යන්තර ශ්‍රිතය නිර්මාණය වන තෙක් බලා සිටීමේ හැකියාව ඇත.
dlaliberte

9
Et බීට්රූට්-බීට්රූට් අපට අභ්‍යන්තර ශ්‍රිතයක් ඇති අතර එය පිටත ශ්‍රිතය නැවත පැමිණීමට පෙර භාවිතා කරන වෙනත් ශ්‍රිතයකට සම්ප්‍රේෂණය වේ යැයි සිතමු. තවද අපි බාහිර ශ්‍රිතයෙන් එකම අභ්‍යන්තර ශ්‍රිතය නැවත ලබා ගනිමු. මෙම අවස්ථා දෙකෙහිම එය එකම ශ්‍රිතයක් වේ, නමුත් ඔබ කියන්නේ පිටත ශ්‍රිතය නැවත පැමිණීමට පෙර අභ්‍යන්තර ශ්‍රිතය ඇමතුම් තොගයට “බැඳී” ඇති අතර එය නැවත පැමිණි පසු අභ්‍යන්තර ශ්‍රිතය හදිසියේම වසා දැමීමකට බැඳී ඇති බවයි. එය අවස්ථා දෙකේදීම එක හා සමානව හැසිරේ; අර්ථ නිරූපණය සමාන වේ, එබැවින් ඔබ ක්‍රියාත්මක කිරීමේ විස්තර ගැන පමණක් කතා කරන්නේ නැද්ද?
dlaliberte

7
@ බීට්රූට්-බීට්රූට්, ඔබගේ ප්‍රතිපෝෂණයට ස්තූතියි, ඔබ ගැන සිතීම ගැන මම සතුටු වෙමි. පිටත ශ්‍රිතයේ සජීවී සන්දර්භය සහ ශ්‍රිතය නැවත පැමිණෙන විට එය වසා දැමීමේදී එම සන්දර්භය අතර කිසිදු අර්ථකථන වෙනසක් මට තවමත් නොපෙනේ (මම ඔබේ අර්ථ දැක්වීම තේරුම් ගන්නේ නම්). අභ්‍යන්තර ශ්‍රිතය ගණන් ගන්නේ නැත. අභ්‍යන්තර ශ්‍රිතය සන්දර්භය / වසා දැමීම යන දෙකටම යොමු කිරීමක් පවත්වා ගෙන යන බැවින් කසළ එකතු කිරීම වැදගත් නොවේ. පිටත ශ්‍රිතය අමතන්නා ඇමතුම් සන්දර්භය වෙත යොමු කිරීම අතහැර දමයි. නමුත් එය මිනිසුන්ට ව්‍යාකූල වන අතර සමහර විට එය ඇමතුම් සන්දර්භයක් ලෙස හැඳින්වීම වඩා හොඳය.
dlaliberte

9
එම ලිපිය කියවීම දුෂ්කර ය, නමුත් එය ඇත්ත වශයෙන්ම මා පවසන දෙයට සහය දක්වයි. එය මෙසේ කියයි: "වසා දැමීමක් සෑදී ඇත්තේ ශ්‍රිත වස්තුවක් ආපසු ලබා දීමෙන් [...] හෝ එවැනි ශ්‍රිත වස්තුවකට සෘජුවම යොමු කිරීම, උදාහරණයක් ලෙස ගෝලීය විචල්‍යයකට ය." GC අදාල නොවන බව මම අදහස් නොකරමි. ඒ වෙනුවට, GC නිසාත්, අභ්‍යන්තර ශ්‍රිතය බාහිර ශ්‍රිතයේ ඇමතුම් සන්දර්භයට (හෝ [[විෂය පථය] ලිපියේ සඳහන් පරිදි) අමුණා ඇති නිසාත්, පිටත ශ්‍රිත ඇමතුම නැවත පැමිණෙන්නේද යන්න ගැටළුවක් නොවේ. ක්‍රියාකාරිත්වය වැදගත් දෙයයි.
dlaliberte

3
නියම පිළිතුර! ඔබ එකතු කළ යුතු එක් දෙයක් නම්, සියලු කාර්යයන් අර්ථ දක්වා ඇති ක්‍රියාත්මක කිරීමේ විෂය පථයේ සමස්ත අන්තර්ගතයට වඩා සමීප වීමයි. මව් විෂය පථයෙන් ඔවුන් සමහරක් හෝ කිසිවක් සඳහන් කළත් කමක් නැත: මව් විෂය පථයේ ශබ්දකෝෂ පරිසරය පිළිබඳ සඳහනක් කොන්දේසි විරහිතව [[විෂය පථය] ලෙස ගබඩා කර ඇත. ECMA පිරිවිතරයේ ක්‍රියාකාරීත්වය නිර්මාණය කිරීම පිළිබඳ කොටසින් මෙය දැකගත හැකිය.
අසාද් සයීදින්

236

මම බ්ලොග් සටහනක් ලිව්වේ ටික කලකට පෙර වසා දැමීම් පැහැදිලි කරමිනි. මෙන්න මම ඔබට වසා දැමීම් ගැන කී දේ ඔබට අවශ්‍ය ඇයි යන්න අනුව .

වසා දැමීම් යනු ශ්‍රිතයකට අඛණ්ඩ, පුද්ගලික විචල්‍යයන් ඇති කිරීමට ඉඩ සලසන ක්‍රමයකි - එනම්, එක් ශ්‍රිතයක් පමණක් දන්නා විචල්‍යයන්, එය ක්‍රියාත්මක වූ පෙර කාලවල තොරතුරු නිරීක්ෂණය කළ හැකි ය.

ඒ අර්ථයෙන් ගත් කල, ඔවුන් ශ්‍රිතයක් පෞද්ගලික ගුණාංග සහිත වස්තුවක් මෙන් ක්‍රියා කිරීමට ඉඩ දෙයි.

සම්පූර්ණ ලිපිය:

ඉතින් මේ වසා දැමීමේ දේවල් මොනවාද?


වසා දැමීමේ ප්‍රධාන වාසිය මෙම උදාහරණයෙන් අවධාරණය කළ හැකිද? මට ශ්‍රිත ඊමේල් දෝෂයක් ඇති බව පවසන්න (sendToAddress, errorString) එවිට මට පැවසිය හැකි අතර පසුව devError = emailError("devinrhode2@googmail.com", errorString)හවුල් ඊමේල් දෝෂ ශ්‍රිතයක මගේ අභිරුචි අනුවාදයක් තිබේද?
ඩෙවින් ජී රෝඩ්

(වසා දැමීමේ දේවල්) වෙත සබැඳියේ ඇති මෙම පැහැදිලි කිරීම සහ ඒ හා බැඳුණු පරිපූර්ණ උදාහරණය වසා දැමීම් අවබෝධ කර ගැනීමේ හොඳම ක්‍රමය වන අතර ඉහළින්ම තිබිය යුතුය!
හෝප්කිං

215

වසා දැමීම් සරලයි:

පහත සරල උදාහරණය ජාවාස්ක්‍රිප්ට් වැසීමේ සියලුම ප්‍රධාන කරුණු ආවරණය කරයි. *  

එකතු කර ගුණ කළ හැකි කැල්කියුලේටර නිපදවන කර්මාන්ත ශාලාවක් මෙන්න:

function make_calculator() {
  var n = 0; // this calculator stores a single number n
  return {
    add: function(a) {
      n += a;
      return n;
    },
    multiply: function(a) {
      n *= a;
      return n;
    }
  };
}

first_calculator = make_calculator();
second_calculator = make_calculator();

first_calculator.add(3); // returns 3
second_calculator.add(400); // returns 400

first_calculator.multiply(11); // returns 33
second_calculator.multiply(10); // returns 4000

වන ප්රධාන කාරණය: කිරීමට එක් එක් ඇමතුමකට make_calculatorනව දේශීය විචල්ය නිර්මාණය nබව කැල්ක්යුලේටරය ගේ විසින් භාවිතා කිරීමට හැකි වන දිගටම කරන addහා multiplyබොහෝ කලකට පසු, කාර්යයන් make_calculatorප්රතිලාභ.

ඔබ රාමු රාමු ගැන හුරුපුරුදු නම්, මෙම කැල්කියුලේටරයන් අමුතු බවක් පෙනේ: ප්‍රතිලාභ nලැබීමෙන් පසු ඒවා දිගටම ප්‍රවේශ වන්නේ කෙසේද make_calculator? පිළිතුර නම්, ජාවාස්ක්‍රිප්ට් "සිරස් රාමු" භාවිතා නොකරන බව සිතීමයි, නමුත් ඒ වෙනුවට "ගොඩවල් රාමු" භාවිතා කරයි, එමඟින් ඒවා නැවත පැමිණීමට හේතු වූ ක්‍රියාකාරී ඇමතුමෙන් පසුවද පැවතිය හැකිය.

වැනි අභ්යන්තර කටයුතු addසහ multiplyප්රවේශය විචල්ය පිටත කාර්යය දී ප්රකාශයට පත් කරන ලද, ** , ලෙස හැඳින්වේ වසා දැමීම් .

වසා දැමීම සඳහා ඇති සියල්ලම එයයි.



* නිදසුනක් ලෙස, 6 වන උදාහරණය හැර, වෙනත් පිළිතුරක දී ඇති “ඩම්මි සඳහා වසා දැමීම්” ලිපියේ ඇති සියලුම කරුණු ආවරණය කරයි , එය සරලව පෙන්වන්නේ විචල්‍යයන් ප්‍රකාශයට පත් කිරීමට පෙර භාවිතා කළ හැකි බව දැන ගැනීමට හොඳ කරුණක් නමුත් වසා දැමීමට සම්පූර්ණයෙන්ම සම්බන්ධ නැති බවය. (1) ශ්‍රිතයන් ඔවුන්ගේ තර්ක දේශීය විචල්‍යයන් වෙත පිටපත් කරන (නම් කරන ලද ශ්‍රිත තර්ක) සහ (2) සංඛ්‍යා පිටපත් කිරීමෙන් නව අංකයක් නිර්මාණය වන නමුත් වස්තු යොමු කිරීමක් පිටපත් කිරීම හැර, පිළිගත් පිළිතුරෙහි ඇති සියලුම කරුණු ද එය ආවරණය කරයි. එකම වස්තුවට තවත් සඳහනක් ලබා දෙයි. මේවා දැන ගැනීමටත් හොඳයි, නමුත් නැවත වසා දැමීමට සම්පූර්ණයෙන්ම සම්බන්ධ නැහැ. එය මෙම පිළිතුරේ ඇති උදාහරණයට ද බොහෝ සෙයින් සමාන නමුත් ටිකක් කෙටි හා අඩු වියුක්ත ය. එය කාරණය ආවරණය නොකරයිමෙම පිළිතුර හෝ ධාරාව සම්බන්ධ කිරීම මෙම විවරණය, එය ජාවාස්ක්‍රිප්ට් මඟින් ප්ලග් කිරීම අපහසු කරයිඔබේ අභ්‍යන්තර ශ්‍රිතයට ලූප් විචල්‍යයක අගය: “ප්ලග් ඉන්” පියවර කළ හැක්කේ ඔබේ අභ්‍යන්තර ශ්‍රිතය ආවරණය වන සහ එක් එක් ලූප් පුනරාවර්තනය මත ක්‍රියාත්මක වන සහායක ශ්‍රිතයකින් පමණි. (නිශ්චිතවම කිවහොත්, අභ්‍යන්තර ශ්‍රිතය කිසිවක් සම්බන්ධ කර ඇතිවාට වඩා විචල්‍යයේ සහායක ශ්‍රිතයේ පිටපතට ප්‍රවේශ වේ.) නැවතත්, වසා දැමීම් නිර්මාණය කිරීමේදී ඉතා ප්‍රයෝජනවත් වේ, නමුත් වසා දැමීමක හෝ එය ක්‍රියා කරන ආකාරයෙහි කොටසක් නොවේ. එම්එල් වැනි ක්‍රියාකාරී භාෂාවල වෙනස් ලෙස ක්‍රියා කිරීම නිසා අමතර ව්‍යාකූලතාවයක් ඇති අතර, විචල්‍යයන් ගබඩා අවකාශයට වඩා අගයන්ට බැඳී ඇති අතර, යම් ආකාරයකින් වසා දැමීම් තේරුම් ගන්නා පුද්ගලයන්ගේ නිරන්තර ප්‍රවාහයක් සපයයි (එනම් “ප්ලග් ඉන්”) ජාවාස්ක්‍රිප්ට් සඳහා සරලවම වැරදියි, එහිදී විචල්‍යයන් සැමවිටම ගබඩා අවකාශයට බැඳී ඇති අතර කිසි විටෙකත් අගයන්ට යටත් නොවේ.

** මෙම පිළිතුර පැහැදිලිව පෙන්වා දෙන පරිදි, ඕනෑම බාහිර ශ්‍රිතයක්, කිහිපයක් කූඩු කර තිබේ නම් හෝ ගෝලීය සන්දර්භය තුළ වුවද .


ඔබ ඇමතුවේ නම් කුමක් සිදුවේද: second_calculator = first_calculator (); second_calculator වෙනුවට = make_calculator (); ? එක හා සමාන විය යුතුයි නේද?
රොනන් ෆෙස්ටින්ගර්

4
On රොනන්: first_calculatorවස්තුවක් බැවින් (ශ්‍රිතයක් නොවේ) ඔබ වරහන් වර්‍ග භාවිතා නොකළ යුතුය second_calculator = first_calculator;, මන්ද එය පැවරුමක් මිස ක්‍රියාකාරී ඇමතුමක් නොවේ. ඔබේ ප්‍රශ්නයට පිළිතුරු සැපයීම සඳහා එක ඇමතුමක් පමණක් make_calculator සඳහා ලැබෙනු ඇත, එබැවින් එක් කැල්කියුලේටරයක් ​​පමණක් සෑදිය හැකි අතර පළමු_කල්කියුලේටරය සහ දෙවන_කල්කියුලේටරය යන දෙකම එකම කැල්කියුලේටරය වෙත යොමු වේ, එබැවින් පිළිතුරු 3, 403, 4433, 44330 වේ.
මැට්

204

අවුරුදු හයක දරුවෙකුට මම එය පැහැදිලි කරන්නේ කෙසේද:

වැඩිහිටියන්ට නිවසක් හිමි කර ගත හැක්කේ කෙසේදැයි ඔබ දන්නවාද? මවකට දරුවෙකු සිටින විට, දරුවාට ඇත්තටම කිසිවක් අයිති නැත, නේද? නමුත් එහි දෙමව්පියන්ට නිවසක් ඇත, එබැවින් යමෙකු "ඔබේ නිවස කොහේද?" යනුවෙන් දරුවාගෙන් ඇසූ විට ඔහුට / ඇයට "එම නිවස!" “වසා දැමීම” යනු දරුවාට සෑම විටම (විදේශයක වුවද) එයට නිවසක් ඇති බව පැවසීමට ඇති හැකියාවයි, එය ඇත්ත වශයෙන්ම නිවස අයිති දෙමව්පියන්ගේ වුවද.


200

අවුරුදු 5 ක දරුවෙකුට වසා දැමීම් ඔබට පැහැදිලි කළ හැකිද? *

මම තවමත් සිතන්නේ ගූගල්හි පැහැදිලි කිරීම ඉතා හොඳින් ක්‍රියාත්මක වන අතර එය සංක්ෂිප්ත ය:

/*
*    When a function is defined in another function and it
*    has access to the outer function's context even after
*    the outer function returns.
*
* An important concept to learn in JavaScript.
*/

function outerFunction(someNum) {
    var someString = 'Hey!';
    var content = document.getElementById('content');
    function innerFunction() {
        content.innerHTML = someNum + ': ' + someString;
        content = null; // Internet Explorer memory leak for DOM reference
    }
    innerFunction();
}

outerFunction(1);​

අභ්‍යන්තර ක්‍රියාකාරිත්වය නැවත නොලැබුණත් මෙම උදාහරණය වසා දැමීමක් ඇති බවට සාධනය

* AC # ප්‍රශ්නය


11
පිටත ක්‍රියාකාරිත්වය නැවත පැමිණීමෙන් පසු වසා දැමීම භාවිතා කිරීම පිළිබඳ අදහස් දැක්වීමේ කොටස ආමන්ත්‍රණය නොකළද, වසා දැමීමේ උදාහරණයක් ලෙස කේතය "නිවැරදි" වේ. එබැවින් එය විශිෂ්ට උදාහරණයක් නොවේ. වසා දැමීම භාවිතා කළ හැකි තවත් බොහෝ ක්‍රම තිබේ. උදා: අභ්‍යන්තර ක්‍රියාකාරිත්වය වෙනත් ශ්‍රිතයකට වහාම කැඳවනු ලබන හෝ ගබඩා කර යම් කාලයකට පසුව කැඳවිය හැකි අතර, සෑම අවස්ථාවකදීම එය හැඳින්වූ විට නිර්මාණය කරන ලද පිටත ක්‍රියාකාරී සන්දර්භයට ප්‍රවේශය ඇත.
dlaliberte

6
ysyockit නැත, පාසි වැරදිය. ශ්‍රිතය කවදා හෝ අර්ථ දක්වා ඇති විෂය පථයෙන් ගැලවී ඇත්ද යන්න නොසලකා වසා දැමීමක් නිර්මාණය වන අතර, දෙමව්පියන්ගේ ශබ්දකෝෂ පරිසරය වෙත කොන්දේසි විරහිතව නිර්මාණය කරන ලද සඳහනක් මව් විෂය පථයේ ඇති සියලුම විචල්‍යයන් පිටත හෝ ඇතුළත ආයාචනා කර තිබියදීත්, සියලු කාර්යයන් සඳහා ලබා ගත හැකිය. ඒවා නිර්මාණය කරන ලද විෂය පථය.
අසාද් සයීදින්

176

හොඳ / BAD සංසන්දනයන්ගෙන් මම වඩා හොඳින් ඉගෙන ගැනීමට නැඹුරු වෙමි. යමෙකුට මුණගැසීමට ඉඩ ඇති ක්‍රියාකාරී නොවන කේතයක් අනුගමනය කරමින් වැඩ කිරීමේ කේතය දැකීමට මා කැමතිය. මම සංසන්දනයක් කරන jsFiddle එකක් එකතු කර, මට ඉදිරිපත් කළ හැකි සරලම පැහැදිලි කිරීම් වලට වෙනස්කම් තම්බා ගැනීමට උත්සාහ කරමි.

වසා දැමීම් නිවැරදිව සිදු කර ඇත:

console.log('CLOSURES DONE RIGHT');

var arr = [];

function createClosure(n) {
    return function () {
        return 'n = ' + n;
    }
}

for (var index = 0; index < 10; index++) {
    arr[index] = createClosure(index);
}

for (var index in arr) {
    console.log(arr[index]());
}
  • ඉහත කේතය createClosure(n)තුළ ලූපයේ සෑම නැවතීමේ ක්‍රියාවලියකදීම ආයාචනා කෙරේ. මම විචල්ය නම් ඒ සටහන nඑය බව ඉස්මතු කිරීමට නව නව කාර්යය විෂය පථය නිර්මාණය විචල්ය හා සමාන විචල්ය නොවේ indexපිටත විෂය පථය බැඳී ඇති.

  • මෙය නව විෂය පථයක් නිර්මාණය කරන අතර nඑම විෂය පථයට බැඳී ඇත; මෙයින් අදහස් කරන්නේ අපට වෙන වෙනම විෂය පථ 10 ක් ඇති බවත්, එක් එක් පුනරාවර්තනය සඳහා එකක් ඇති බවත්ය.

  • createClosure(n) එම විෂය පථය තුළ n නැවත ලබා දෙන ශ්‍රිතයක් ලබා දෙයි.

  • එක් එක් විෂය පථය තුළ nඑය createClosure(n)ආයාචනා කරන විට තිබූ ඕනෑම අගයකට බැඳී ඇති බැවින් නැවත ලබා ගන්නා කැදැලි ශ්‍රිතය සැමවිටම ආයාචනා nකළ විට එහි වටිනාකම නැවත ලබා දෙනු ඇත createClosure(n).

වැසීම වැරදියි:

console.log('CLOSURES DONE WRONG');

function createClosureArray() {
    var badArr = [];

    for (var index = 0; index < 10; index++) {
        badArr[index] = function () {
            return 'n = ' + index;
        };
    }
    return badArr;
}

var badArr = createClosureArray();

for (var index in badArr) {
    console.log(badArr[index]());
}
  • ඉහත කේතය තුළ ලූපය createClosureArray()ශ්‍රිතය තුළට ගෙන යන ලද අතර ශ්‍රිතය දැන් සම්පුර්ණ කරන ලද අරාව නැවත ලබා දෙයි, බැලූ බැල්මට එය වඩාත් බුද්ධිමත් බව පෙනේ.

  • පැහැදිලිව පෙනෙන්නට නොතිබිය හැකි දෙය නම්, createClosureArray()මෙම ශ්‍රිතය සඳහා එක් විෂය පථයක් නිර්මාණය කිරීමෙන් එක් වරක් පමණක් ලූපයේ සෑම පුනරාවර්තනයක් සඳහාම එකක් භාවිතා කිරීමයි.

  • මෙම ශ්‍රිතය තුළ විචල්‍යයක් නම් indexකර ඇත. ලූපය ධාවනය වන අතර නැවත පැමිණෙන අරාව වෙත කාර්යයන් එක් කරයි index. එක් වරක් පමණක් ආයාචනා indexකරන createClosureArrayශ්‍රිතය තුළ අර්ථ දක්වා ඇති සටහන .

  • createClosureArray()ශ්‍රිතය තුළ ඇත්තේ එක් විෂය පථයක් පමණක් බැවින් එම විෂය පථය තුළ ඇති indexඅගයකට පමණක් බැඳී ඇත. වෙනත් වචන වලින් කිවහොත්, ලූපයේ වටිනාකම වෙනස් වන සෑම අවස්ථාවකම indexඑය එම විෂය පථය තුළ සඳහන් කරන සෑම දෙයක් සඳහාම එය වෙනස් කරයි.

  • අරාව සඳහා එකතු කරන ලද සියලුම කාර්යයන් indexපළමු උදාහරණය මෙන් විවිධ විෂය පථ 10 කින් වෙනස් 10 ක් වෙනුවට මව් විෂය පථයෙන් SAME විචල්‍යය ලබා දෙයි. අවසාන ප්‍රති result ලය වනුයේ සියලුම කාර්යයන් 10 එකම විචල්‍යයකින් එකම විෂය පථයකින් ලබා දීමයි.

  • ලූපය අවසන් indexකර නවීකරණය කිරීමෙන් පසු අවසාන අගය 10 ක් විය, එබැවින් අරාවට එකතු කරන සෑම ශ්‍රිතයක්ම indexදැන් 10 ට සකසා ඇති තනි විචල්‍යයේ අගය ලබා දෙයි .

ප්‍රති ult ලය

CLOSURES DONE RIGHT
n = 0
n = 1
n = 2
n = 3
n = 4
n = 5
n = 6
n = 7
n = 8
n = 9

වැසීම් වැසී ඇත
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10
n = 10 n = 10


1
එකතු කිරීම හොඳයි, ස්තූතියි. එය වඩාත් පැහැදිලි කර ගැනීම සඳහා එක් එක් නැවතීමේ ක්‍රියාවලිය සමඟ "නරක" අරාව "නරක" ලූපය තුළ නිර්මාණය වන්නේ කෙසේදැයි සිතාගත හැකිය: 1 වන නැවත කිරීම: [ශ්‍රිතය () {ආපසු 'n =' + 0;}] 2 වන ක්‍රියාවලිය: [( ශ්‍රිතය () {ආපසු 'n =' + 1;}), (ශ්‍රිතය () {ආපසු 'n =' + 1;})] 3 වන ක්‍රියාවලිය: [(ශ්‍රිතය () {ආපසු 'n =' + 2;}) , (ශ්‍රිතය () {ආපසු 'n =' + 2;}), (ශ්‍රිතය () {ආපසු 'n =' + 2;})] යනාදිය. එබැවින්, දර්ශක අගය වෙනස් වන සෑම අවස්ථාවකම එය සියලු ශ්‍රිතවලින් පිළිබිඹු වේ දැනටමත් අරාවට එකතු කර ඇත.
ඇලෙක්ස් ඇලෙක්සිව්

3
වෙනස නිවැරදි කිරීම letසඳහා භාවිතා කිරීම var.
රූපම් දත්ත

මෙහි "වසා දැමීම නිවැරදිව සිදු කිරීම" "වසා දැමීම ඇතුළත වසා දැමීම" සඳහා උදාහරණයක් නොවේද?
TechnicalSmile

මම කිව්වේ, සෑම ශ්‍රිතයක්ම තාක්‍ෂණිකව වසා දැමීමක් වන නමුත් වැදගත් කොටස වන්නේ ශ්‍රිතය තුළ නව විචල්‍යයක් නිර්වචනය කිරීමයි. ප්‍රතිලාභ ලබා දෙන ශ්‍රිතය nනව වසා දැමීමක් තුළ නිර්මාණය කරන ලද යොමු කිරීම් පමණි . අපි ශ්‍රිතයක් නැවත ලබා දෙන බැවින් අපට එය අරාවෙහි ගබඩා කර පසුව එය ක්‍රියාත්මක කළ හැකිය.
චෙව්

පළමු පුනරාවර්තනයේ ප්‍රති the ලය අරාවෙහි ගබඩා කිරීමට ඔබට අවශ්‍ය නම් ඔබට එය මේ ආකාරයට පේළිගත කළ හැකිය : arr[index] = (function (n) { return 'n = ' + n; })(index);. නමුත් පසුව ඔබ මගේ ආදර්ශය පරාජය කරන ආයාචනා කිරීමේ ශ්‍රිතයකට වඩා එහි ප්‍රති string ලයක් ලෙස ඇති අරාව අරාව තුළ ගබඩා කරයි.
චෙව්

164

වසා දැමීම් පිළිබඳ විකිපීඩියා :

පරිගණක විද්‍යාවේදී, වසා දැමීම යනු එම ශ්‍රිතයේ ස්ථානීය නොවන නම් (නිදහස් විචල්‍යයන්) සඳහා යොමු කිරීමේ පරිසරයක් සමඟ එක් කිරීමකි.

තාක්ෂණික වශයෙන්, ජාවාස්ක්‍රිප්ට් හි සෑම කාර්යයක්ම වසා දැමීමකි . එය සෑම විටම අවට විෂය පථය තුළ අර්ථ දක්වා ඇති විචල්යයන් සඳහා ප්රවේශයක් ඇත.

සිට JavaScript දී විෂය පථය-නිර්වචනය ඉදිකිරීම් ශ්රිතයක් වේ , වෙනත් බොහෝ භාෂා වලින් වැනි කේතය වාරණ නැහැ, අපි සාමාන්යයෙන් අදහස් වසා JavaScript දී කියන්නේ මේ වන විටත් ක්රියාත්මක අවට කාර්යය අර්ථ nonlocal විචල්ය සමඟ වැඩ උත්සවය .

සමහර සැඟවුණු පුද්ගලික දත්ත සමඟ කාර්යයන් නිර්මාණය කිරීම සඳහා වසා දැමීම් බොහෝ විට භාවිතා වේ (නමුත් එය සැමවිටම එසේ නොවේ).

var db = (function() {
    // Create a hidden object, which will hold the data
    // it's inaccessible from the outside.
    var data = {};

    // Make a function, which will provide some access to the data.
    return function(key, val) {
        if (val === undefined) { return data[key] } // Get
        else { return data[key] = val } // Set
    }
    // We are calling the anonymous surrounding function,
    // returning the above inner function, which is a closure.
})();

db('x')    // -> undefined
db('x', 1) // Set x to 1
db('x')    // -> 1
// It's impossible to access the data object itself.
// We are able to get or set individual it.

ems

ඉහත උදාහරණය නම් එක් වරක් ක්‍රියාත්මක කරන ලද නිර්නාමික ශ්‍රිතයක් භාවිතා කිරීමයි. නමුත් එය එසේ විය යුතු නැත. එය නම් කළ හැකිය (උදා mkdb) පසුව ක්‍රියාත්මක කළ හැකි අතර , එය ක්‍රියාත්මක කරන සෑම අවස්ථාවකම දත්ත සමුදා ශ්‍රිතයක් ජනනය කරයි. උත්පාදනය කරන ලද සෑම ශ්‍රිතයකටම එහි සැඟවුණු දත්ත සමුදා වස්තුවක් ඇත. වසා දැමීමේ තවත් භාවිත නිදසුනක් නම්, අප ශ්‍රිතයක් ආපසු නොදෙන විට, නමුත් විවිධ අරමුණු සඳහා විවිධ කාර්යයන් අඩංගු වස්තුවක්, එම එක් එක් ශ්‍රිතයට එකම දත්ත වලට ප්‍රවේශය ඇත.


2
ජාවාස්ක්‍රිප්ට් වැසීම සඳහා හොඳම පැහැදිලි කිරීම මෙයයි. තෝරාගත් පිළිතුර විය යුතුය. ඉතිරිය ප්‍රමාණවත් තරම් විනෝදජනක වන නමුත් මෙය සැබෑ ලෝකයේ ජාවාස්ක්‍රිප්ට් කේත සඳහා ප්‍රායෝගිකව ප්‍රයෝජනවත් වේ.
භූ විද්‍යාව

136

වසා දැමීම් ක්‍රියා කරන ආකාරය පැහැදිලි කිරීම සඳහා මම අන්තර්ක්‍රියාකාරී ජාවාස්ක්‍රිප්ට් නිබන්ධනයක් එක් කළෙමි. වසා දැමීම යනු කුමක්ද?

මෙන්න එක් උදාහරණයක්:

var create = function (x) {
    var f = function () {
        return x; // We can refer to x here!
    };
    return f;
};
// 'create' takes one argument, creates a function

var g = create(42);
// g is a function that takes no arguments now

var y = g();
// y is 42 here

128

දෙමව්පියන් අතුරුදහන් වූ පසුවත්, දරුවන් සමඟ ඔවුන් බෙදාගත් රහස් දරුවන්ට සැමවිටම මතක තබා ගත හැකිය. කාර්යයන් සඳහා වසා දැමීම් යනු මෙයයි.

JavaScript කාර්යයන් සඳහා රහස් පුද්ගලික විචල්යයන් වේ

var parent = function() {
 var name = "Mary"; // secret
}

ඔබ එය අමතන සෑම අවස්ථාවකම දේශීය විචල්ය "නම" නිර්මාණය කර "මේරි" යන නම ලබා දී ඇත. ශ්‍රිතයෙන් පිටවන සෑම අවස්ථාවකම විචල්‍යය නැති වී නම අමතක වේ.

ඔබ අනුමාන කළ පරිදි, ශ්‍රිතය හැඳින්වෙන සෑම අවස්ථාවකම විචල්‍යයන් නැවත නිර්මාණය වන අතර වෙන කිසිවෙකු ඒවා නොදැන සිටින බැවින් ඒවා ගබඩා කර ඇති රහස් ස්ථානයක් තිබිය යුතුය. එය වාණිජ මණ්ඩලය හෝ තොගය ලෙස හැඳින්විය හැකිය හෝ දේශීය විෂය පථයක් නමුත් එය ඇත්ත වශයෙන්ම වැදගත් නොවේ. අපි දන්නවා ඔවුන් එහි, කොහේ හරි, මතකයේ සැඟවී සිටින බව.

එහෙත්, ජාවාස්ක්‍රිප්ට් හි මෙම සුවිශේෂී දෙය ඇත්තේ වෙනත් කාර්යයන් තුළ නිර්මාණය වන කාර්යයන් වන අතර, ඔවුන්ගේ දෙමව්පියන්ගේ දේශීය විචල්‍යයන් ද දැන ගත හැකි අතර ඔවුන් ජීවත්වන තාක් කල් ඒවා තබා ගත හැකිය.

var parent = function() {
  var name = "Mary";
  var child = function(childName) {
    // I can also see that "name" is "Mary"
  }
}

එබැවින්, අපි දෙමාපිය ක්‍රියාකාරිත්වයේ සිටින තාක් කල්, රහස් ස්ථානයෙන් රහස් විචල්‍යයන් බෙදා ගන්නා ළමා ක්‍රියාකාරකම් එකක් හෝ කිහිපයක් නිර්මාණය කළ හැකිය.

නමුත් කනගාටුදායක කාරණය නම්, දරුවා ද එහි මව් ක්‍රියාකාරිත්වයේ පෞද්ගලික විචල්‍යයක් නම්, දෙමව්පියන් අවසන් වූ විට එය ද මිය යන අතර රහස් ඔවුන් සමඟ මිය යනු ඇත.

ඒ නිසා ජීවත් වීමට නම්, දරුවා ප්‍රමාද වීමට පෙර පිටව යා යුතුය

var parent = function() {
  var name = "Mary";
  var child = function(childName) {
    return "My name is " + childName  +", child of " + name; 
  }
  return child; // child leaves the parent ->
}
var child = parent(); // < - and here it is outside 

දැන්, මරියා "තවදුරටත් දුවන්නේ නැත" වුවද, ඇයගේ මතකය නැති වී නොයන අතර, ඔවුන් එකට සිටි කාලය තුළ ඇය බෙදාගත් ඇගේ නම සහ වෙනත් රහස් ඇගේ දරුවාට සැමවිටම මතකයේ රැඳෙනු ඇත.

එබැවින්, ඔබ දරුවා "ඇලිස්" ලෙස හැඳින්වුවහොත්, ඇය ප්රතිචාර දක්වනු ඇත

child("Alice") => "My name is Alice, child of Mary"

කියන්න තියෙන්නේ එච්චරයි.


15
තාක්ෂණික යෙදුම් පිළිබඳ සැලකිය යුතු පූර්ව දැනුමක් උපකල්පනය නොකරන නිසා මෙය මට වඩාත් අර්ථවත් කළ පැහැදිලි කිරීමයි. මෙහි ඉහළින්ම ඡන්දය දුන් පැහැදිලි කිරීම උපකල්පනය කරන්නේ වසා දැමීම් තේරුම් නොගන්නා පුද්ගලයාට 'ශබ්දකෝෂ විෂය පථය' සහ 'ක්‍රියාත්මක කිරීමේ සන්දර්භය' වැනි වචන පිළිබඳ පූර්ණ හා පූර්ණ අවබෝධයක් ඇති බවය - මට මේවා සංකල්පමය වශයෙන් තේරුම් ගත හැකි වුවත්, මම හිතන්නේ නැහැ මා විය යුතු ආකාරයට ඒවායේ විස්තර සමඟ සැපපහසු වන අතර, එහි කිසිදු ප්‍රභාෂයක් නොමැති පැහැදිලි කිරීමක් වන්නේ වසා දැමීම් අවසානයේ මා සඳහා ක්ලික් කිරීමයි, ස්තූතියි. ප්‍රසාද දීමනාවක් ලෙස, එය ඉතා සංක්ෂිප්තව ඇති විෂය පථය ද පැහැදිලි කරයි.
එමා ඩබ්

103

මෙහි පිළිතුරු මෙතරම් සංකීර්ණ වන්නේ මන්දැයි මට තේරෙන්නේ නැත.

මෙන්න වසා දැමීමක්:

var a = 42;

function b() { return a; }

ඔව්. ඔබ බොහෝ විට එය දිනකට බොහෝ වාරයක් භාවිතා කරයි.


වසා දැමීම් විශේෂිත ගැටළු වලට විසඳුම් සෙවීම සඳහා සංකීර්ණ මෝස්තරයක් යැයි විශ්වාස කිරීමට හේතුවක් නැත. නැත, වසා දැමීම් යනු ඉහළ විෂය පථයකින් එන විචල්‍යයක් භාවිතා කිරීම පමණි ශ්‍රිතය ප්‍රකාශයට පත් කළ ස්ථානයේ දෘෂ්ටි කෝණයෙන් (ක්‍රියාත්මක නොවේ) .

දැන් එය ඔබට කිරීමට ඉඩ දෙන දේ වඩාත් දර්ශනීය විය හැකිය, වෙනත් පිළිතුරු බලන්න.


5
මෙම පිළිතුර සැකසීමට මිනිසුන්ට උදව් වන බවක් නොපෙනේ. සාම්ප්රදායික පරිගණක භාෂාවෙන් ඒ රළු සමාන බව, වස්තුවක් මත ක්රමයක් ලෙස ආ () නිර්මාණය කිරීමට විය හැකි පෞද්ගලික නිරන්තර හෝ දේපළ a. මගේ මතකයට අනුව, ජේඑස් විෂය පථය නියතයකට aවඩා දේපලක් ලෙස effectively ලදායී ලෙස සපයයි . එම වැදගත් හැසිරීම ඔබ වෙනස් කරන්නේ නම් පමණක් ඔබ දකිනු ඇතreturn a++;
ජෝන් කුම්බ්ස්

1
හරියටම ජෝන් කියපු දේ. අවසාන වශයෙන් වසා දැමීමට පෙර මට ප්‍රායෝගික උදාහරණ සොයා ගැනීමට අපහසු විය. ඔව්, ෆ්ලොරිබන් වැසීමක් ඇති කළේය, නමුත් මා නූගත් නම් මෙය මට කිසිවක් උගන්වනු ඇත.
චෙව්

3
වසා දැමීම යනු කුමක්ද යන්න මෙයින් නිර්වචනය නොවේ - එය හුදෙක් එකක් භාවිතා කරන උදාහරණයකි. විෂය පථය අවසන් වූ විට කුමක් සිදුවේද යන්න එහි ආමන්ත්‍රණය නොකරයි. සියලුම විෂය පථයන් තවමත් පවතින විට සහ විශේෂයෙන් ගෝලීය විචල්‍යයකදී, ශබ්දකෝෂ විෂය පථය පිළිබඳව කිසිවෙකුට ප්‍රශ්නයක් ඇතැයි මම නොසිතමි.
ජෙරාඩ් ඔනිල්

92

පළමු ලක්ෂ්‍යය සඳහා උදාහරණය dlaliberte:

වසා දැමීමක් නිර්මාණය වන්නේ ඔබ අභ්‍යන්තර ශ්‍රිතයක් නැවත ලබා දෙන විට පමණක් නොවේ. ඇත්ත වශයෙන්ම, කොටු කිරීමේ කාර්යයට කිසිසේත් ආපසු යාමට අවශ්‍ය නොවේ. ඔබට ඒ වෙනුවට ඔබේ අභ්‍යන්තර ශ්‍රිතය බාහිර විෂය පථයක විචල්‍යයකට පැවරිය හැකිය, නැතහොත් එය වහාම භාවිතා කළ හැකි වෙනත් ශ්‍රිතයකට තර්කයක් ලෙස යොමු කළ හැකිය. එමනිසා, ඕනෑම අභ්‍යන්තර ශ්‍රිතයක් හැඳින්වූ විගසම එයට ප්‍රවේශ විය හැකි බැවින්, සංවෘත ශ්‍රිතය වසා දැමීමේ ක්‍රියාවලිය දැනටමත් හැඳින්විය හැක.

var i;
function foo(x) {
    var tmp = 3;
    i = function (y) {
        console.log(x + y + (++tmp));
    }
}
foo(2);
i(3);

විය හැකි අවිනිශ්චිතතාවයක් පිළිබඳ කුඩා පැහැදිලි කිරීමක්. මම "ඇත්ත වශයෙන්ම, කොටු කිරීමේ කාර්යය කිසිසේත් ආපසු යාමට අවශ්ය නොවේ." මම අදහස් කළේ "කිසිදු වටිනාකමක් ලබා නොදෙන්න" නමුත් "තවමත් ක්‍රියාකාරී" යන්නයි. එබැවින් උදාහරණය එම අංගය නොපෙන්වයි, නමුත් එය අභ්‍යන්තර ශ්‍රිතය බාහිර විෂය පථයට යැවිය හැකි වෙනත් ක්‍රමයක් පෙන්වයි. කිරීමට මම උත්සාහ කළා ප්රධාන කරුණ ගැන ය කාලය සමහර අය විට කවරෙ ශ්රිතයේ එය සිදු හිතන්න දෙයක් බැවින්, (කවරෙ කාර්යය සඳහා) වසා දැමීම නිර්මාණය. ශ්‍රිතයක් හැඳින්වූ විට වසා දැමීම නිර්මාණය වී ඇති බව පෙන්වීමට වෙනත් උදාහරණයක් අවශ්‍ය වේ .
dlaliberte

89

වසා දැමීම යනු අභ්‍යන්තර ශ්‍රිතයකට එහි බාහිර ශ්‍රිතයේ විචල්‍යයන්ට ප්‍රවේශය ඇති ස්ථානයකි. වසා දැමීම සඳහා ඔබට ලබා ගත හැකි සරලම එක්-පේළියේ පැහැදිලි කිරීම එය විය හැකිය.


35
එය පැහැදිලි කිරීමෙන් අඩක් පමණි. වසා දැමීම් පිළිබඳව සැලකිල්ලට ගත යුතු වැදගත්ම දෙය නම්, පිටත ශ්‍රිතය පිටව ගිය පසු අභ්‍යන්තර ශ්‍රිතය තවමත් සඳහන් කරන්නේ නම්, පිටත ශ්‍රිතයේ පැරණි අගයන් තවමත් අභ්‍යන්තරයට ලබා ගත හැකිය.
pcorcoran

22
ඇත්ත වශයෙන්ම, අභ්‍යන්තර ශ්‍රිතයට ලබා ගත හැක්කේ පිටත ශ්‍රිතයේ පැරණි අගයන් නොව, පැරණි විචල්‍යයන් ය , යම් ශ්‍රිතයක් වෙනස් කිරීමට හැකි වුවහොත් නව අගයන් තිබිය හැකිය.
dlaliberte

86

දැනටමත් විසඳුම් ඕනෑ තරම් ඇති බව මම දනිමි, නමුත් මෙම කුඩා හා සරල පිටපත සංකල්පය නිරූපණය කිරීමට ප්‍රයෝජනවත් වනු ඇතැයි මම සිතමි:

// makeSequencer will return a "sequencer" function
var makeSequencer = function() {
    var _count = 0; // not accessible outside this function
    var sequencer = function () {
        return _count++;
    }
    return sequencer;
}

var fnext = makeSequencer();
var v0 = fnext();     // v0 = 0;
var v1 = fnext();     // v1 = 1;
var vz = fnext._count // vz = undefined

82

ඔබ නිදාගෙන සිටින අතර ඔබ ඩෑන්ට ආරාධනා කරයි. ඔබ ඩෑන්ට කියනවා එක් එක්ස් බොක්ස් පාලකයක් ගෙනෙන්න කියලා.

දාන් පාවුල්ට ආරාධනා කරයි. එක් පාලකයෙකු ගෙන එන ලෙස ඩෑන් පෝල්ගෙන් ඉල්ලා සිටී. පාලකයන් කීයක් පක්ෂයට ගෙන ආවාද?

function sleepOver(howManyControllersToBring) {

    var numberOfDansControllers = howManyControllersToBring;

    return function danInvitedPaul(numberOfPaulsControllers) {
        var totalControllers = numberOfDansControllers + numberOfPaulsControllers;
        return totalControllers;
    }
}

var howManyControllersToBring = 1;

var inviteDan = sleepOver(howManyControllersToBring);

// The only reason Paul was invited is because Dan was invited. 
// So we set Paul's invitation = Dan's invitation.

var danInvitedPaul = inviteDan(howManyControllersToBring);

alert("There were " + danInvitedPaul + " controllers brought to the party.");

80

කතුවරයා බඳුන්වලට අපි ඔවුන්ට අවශ්ය හේතුව පැහැදිලි සහ අවබෝධය වසා දැමීම් සඳහා අවශ්ය වන්නා වූ LexicalEnvironment පැහැදිලි, ඉතා හොදින් වසා පැහැදිලි කර ඇත.
සාරාංශය මෙන්න:

විචල්‍යයකට ප්‍රවේශ වුවහොත් එය දේශීය නොවේ නම් කුමක් කළ යුතුද? මෙහි මෙන්:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

මෙම අවස්ථාවේ දී, පරිවර්තකයා පිටත විචල්‍යය සොයා ගනී LexicalEnvironment වස්තුවෙහි .

ක්‍රියාවලිය පියවර දෙකකින් සමන්විත වේ:

  1. පළමුව, f ශ්‍රිතයක් නිර්මාණය කළ විට එය හිස් අවකාශයක නිර්මාණය නොවේ. වර්තමාන ලෙක්සිකල් පාරිසරික වස්තුවක් ඇත. ඉහත අවස්ථාවෙහිදී, එහි කවුළුව (ශ්‍රිතය නිර්මාණය කරන අවස්ථාවේ දී නිර්වචනය කර නොමැත).

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ශ්‍රිතයක් නිර්මාණය කළ විට, එය [[විෂය පථය]] නමින් සැඟවුණු දේපලක් ලබා ගනී, එය වර්තමාන ලෙක්සිකල් පරිසරය ගැන සඳහන් කරයි.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

විචල්‍යයක් කියවා, නමුත් කොතැනකවත් සොයාගත නොහැකි නම්, දෝෂයක් ජනනය වේ.

කැදැලි කාර්යයන්

කාර්යයන් එකිනෙක තුළ කූඩු කළ හැකි අතර එය ලෙක්සිකල් පරිසර දාමයක් සාදයි, එය විෂය පථ දාමයක් ලෙසද හැඳින්විය හැකිය.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

එබැවින්, g ශ්‍රිතයට g, a සහ f වෙත ප්‍රවේශය ඇත.

වසා දැමීම්

පිටත ශ්‍රිතය අවසන් වූ පසු කැදැලි ශ්‍රිතයක් දිගටම පැවතිය හැකිය:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ලෙක්සිකල් පරිසරයන් සලකුණු කිරීම:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

අප දකින පරිදි, this.say පරිශීලක වස්තුවෙහි ඇති දේපලකි, එබැවින් එය පරිශීලකයා සම්පූර්ණ කිරීමෙන් පසුවද දිගටම පවතී.

ඔබට මතක නම්, this.sayනිර්මාණය කරන විට , එය (සෑම ශ්‍රිතයක්ම) this.say.[[Scope]]වත්මන් ලෙක්සිකල් පරිසරය පිළිබඳ අභ්‍යන්තර සඳහනක් ලබා ගනී. එබැවින්, වර්තමාන පරිශීලක ක්‍රියාත්මක කිරීමේ ලෙක්සිකල් පරිසරය මතකයේ රැඳේ. පරිශීලකයාගේ සියලු විචල්‍යයන් ද එහි ගුණාංග වේ, එබැවින් ඒවා ද ප්‍රවේසමෙන් තබා ඇත.

සමස්ත කාරණය වන්නේ අභ්‍යන්තර ශ්‍රිතයට අනාගතයේදී බාහිර විචල්‍යයකට ප්‍රවේශ වීමට අවශ්‍ය නම් එය කළ හැකි බව සහතික කිරීමයි.

සාරාංශ ගත කිරීමට:

  1. අභ්‍යන්තර ශ්‍රිතය පිටත ලෙක්සිකල් පරිසරයට යොමු දක්වයි.
  2. පිටත ශ්‍රිතය අවසන් වුවද අභ්‍යන්තර ශ්‍රිතය ඕනෑම වේලාවක එයින් විචල්‍යයන්ට ප්‍රවේශ විය හැකිය.
  3. අභ්‍යන්තර ශ්‍රිතයක් සඳහන් වන තෙක් බ්‍රව්සරය ලෙක්සිකල් පරිසරය සහ එහි සියලු ගුණාංග (විචල්‍යයන්) මතකයේ තබා ගනී.

මෙය වසා දැමීමක් ලෙස හැඳින්වේ.


78

ජාවාස්ක්‍රිප්ට් ශ්‍රිතවලට ඒවාට ප්‍රවේශ විය හැකිය:

  1. තර්ක
  2. ස්ථාන (එනම්, ඒවායේ දේශීය විචල්‍යයන් සහ දේශීය කාර්යයන්)
  3. පරිසරය,
    • DOM ඇතුළු ගෝලීය
    • බාහිර කාර්යයන් වල ඕනෑම දෙයක්

ශ්‍රිතයක් එහි පරිසරයට ප්‍රවේශ වන්නේ නම්, එම ශ්‍රිතය වසා දැමීමකි.

බාහිර කාර්යයන් අවශ්‍ය නොවන බව සලකන්න, ඒවා ප්‍රතිලාභ ලබා දුන්නද මම මෙහි සාකච්ඡා නොකරමි. එහි පරිසරය තුළ දත්ත වලට ප්‍රවේශ වීමෙන්, වසා දැමීමක් එම දත්ත සජීවීව තබා ගනී. පිටත / අභ්‍යන්තර ශ්‍රිතවල උප කොටසේදී, බාහිර ශ්‍රිතයකට දේශීය දත්ත නිර්මාණය කර අවසානයේ පිටවිය හැකි අතර, කෙසේ වෙතත්, බාහිර ශ්‍රිතය පිටවීමෙන් පසු කිසියම් අභ්‍යන්තර ශ්‍රිතයක් නොනැසී පවතී නම්, අභ්‍යන්තර ශ්‍රිතය (ය) බාහිර ශ්‍රිතයේ දේශීය දත්ත තබා ගනී පණපිටින්.

ගෝලීය පරිසරය භාවිතා කරන වසා දැමීමේ උදාහරණය:

ගෝලීය විචල්‍යයන් ලෙස අර්ථ දක්වා ඇති බාහිර විචල්‍යයන් සඳහා ප්‍රවේශය ඇති වසා දැමීම්, ඡන්දය-ක්ලික් සහ ඡන්ද ඩවුන්_ක්ලික් ලෙස තොග පිටාර ගැලීමේ ඡන්දය සහ ඡන්ද-පහළ බොත්තම් සිදුවීම් ක්‍රියාත්මක වේ යැයි සිතන්න. (සරල බව නිසාම, මම යොමු කරන්නේ ස්ටැක් ඕවර්ෆ්ලෝගේ ප්‍රශ්න ඡන්ද බොත්තම් මිස පිළිතුරු ඡන්ද බොත්තම් පෙළ නොවේ.)

පරිශීලකයා VoteUp බොත්තම ක්ලික් කළ විට, ඡන්දය ප්‍රකාශ කළ යුතුද නැතිනම් හුදෙක් ඡන්දය අවලංගු කළ යුතුද යන්න තීරණය කිරීම සඳහා ඡන්දය ප්‍රකාශ කිරීම = VotDown == සත්‍ය දැයි පරීක්ෂා කරයි. VotUp_click ශ්‍රිතය එහි පරිසරයට ප්‍රවේශ වන නිසා එය වසා දැමීමකි.

var isVotedUp = false;
var isVotedDown = false;

function voteUp_click() {
  if (isVotedUp)
    return;
  else if (isVotedDown)
    SetDownVote(false);
  else
    SetUpVote(true);
}

function voteDown_click() {
  if (isVotedDown)
    return;
  else if (isVotedUp)
    SetUpVote(false);
  else
    SetDownVote(true);
}

function SetUpVote(status) {
  isVotedUp = status;
  // Do some CSS stuff to Vote-Up button
}

function SetDownVote(status) {
  isVotedDown = status;
  // Do some CSS stuff to Vote-Down button
}

මෙම කාර්යයන් හතරම ඔවුන්ගේ පරිසරයට ප්‍රවේශ වන බැවින් වසා දැමීම් වේ.


59

වයස අවුරුදු 6 ක පියෙකු ලෙස, දැනට කුඩා දරුවන්ට උගන්වන (සහ විධිමත් අධ්‍යාපනයක් නොමැතිව කේතීකරණය කිරීමට සාමනේර සාමනේරයකු වන බැවින් නිවැරදි කිරීම් අවශ්‍ය වනු ඇත), මම සිතන්නේ පාඩම වඩාත් හොඳින් ක්‍රීඩා කිරීම තුළින් ක්‍රියාත්මක වනු ඇති බවයි. වසා දැමීම යනු කුමක්දැයි වටහා ගැනීමට 6 හැවිරිදි දරුවා සූදානම් නම්, ඔවුන් තනිවම යාමට තරම් වයසයි. කේතය jsfiddle.net වෙත ඇලවීම, ටිකක් පැහැදිලි කිරීම සහ අද්විතීය ගීතයක් රචනා කිරීම සඳහා ඒවා තනිවම තැබීම මම යෝජනා කරමි. පහත දැක්වෙන පැහැදිලි කිරීමේ පා text ය අවුරුදු 10 ක දරුවෙකුට වඩාත් සුදුසු ය.

function sing(person) {

    var firstPart = "There was " + person + " who swallowed ";

    var fly = function() {
        var creature = "a fly";
        var result = "Perhaps she'll die";
        alert(firstPart + creature + "\n" + result);
    };

    var spider = function() {
        var creature = "a spider";
        var result = "that wiggled and jiggled and tickled inside her";
        alert(firstPart + creature + "\n" + result);
    };

    var bird = function() {
        var creature = "a bird";
        var result = "How absurd!";
        alert(firstPart + creature + "\n" + result);
    };

    var cat = function() {
        var creature = "a cat";
        var result = "Imagine That!";
        alert(firstPart + creature + "\n" + result);
    };

    fly();
    spider();
    bird();
    cat();
}

var person="an old lady";

sing(person);

උපදෙස්

දත්ත: දත්ත යනු කරුණු එකතුවකි. එය සංඛ්‍යා, වචන, මිනුම්, නිරීක්ෂණ හෝ දේවල් විස්තර කිරීමක් විය හැකිය. ඔබට එය ස්පර්ශ කිරීමට, සුවඳ දැනීමට හෝ රස බැලීමට නොහැකිය. ඔබට එය ලිවීමට, කථා කිරීමට හා ඇසීමට හැකිය. ඔබට එය නිර්මාණය කිරීමට භාවිතා කළ හැකියපරිගණකයක් භාවිතයෙන් ස්පර්ශ සුවඳ සහ රසය . කේතය භාවිතා කරන පරිගණකයකට එය ප්‍රයෝජනවත් කළ හැකිය.

කේතය: ඉහත සියලුම ලිවීම් හැඳින්වේ කේතය . එය ජාවාස්ක්‍රිප්ට් හි ලියා ඇත.

ජාවාස්ක්‍රිප්ට්: ජාවාස්ක්‍රිප්ට් යනු භාෂාවකි. ඉංග්‍රීසි හෝ ප්‍රංශ හෝ චීන වැනි භාෂා වේ. පරිගණක සහ වෙනත් ඉලෙක්ට්‍රොනික සකසනයන් විසින් තේරුම් ගත හැකි භාෂා රාශියක් ඇත. ජාවාස්ක්‍රිප්ට් පරිගණකයක් මගින් තේරුම් ගැනීමට එයට පරිවර්තකයෙකු අවශ්‍ය වේ. රුසියානු භාෂාව පමණක් කතා කරන ගුරුවරයෙක් පාසැලේදී ඔබේ පන්තිය ඉගැන්වීමට පැමිණේ නම් සිතා බලන්න. ගුරුවරයා "все садятся" යැයි පැවසූ විට පන්තියට තේරෙන්නේ නැත. නමුත් වාසනාවකට මෙන් ඔබේ පන්තියේ රුසියානු සිසුවෙකු සිටින අතර සෑම කෙනෙකුම මෙයින් අදහස් කරන්නේ "හැමෝම වාඩි වී සිටින්න" යන්නයි. පංතිය පරිගණකයක් වැනි වන අතර රුසියානු ශිෂ්‍යයා පරිවර්ථකයා වේ. ජාවාස්ක්‍රිප්ට් සඳහා වඩාත් පොදු පරිවර්තකය බ්‍රව්සරයක් ලෙස හැඳින්වේ.

බ්‍රව්සර්: ඔබ වෙබ් අඩවියක් බැලීමට පරිගණකයක්, ටැබ්ලටයක් හෝ දුරකථනයකින් අන්තර්ජාලයට සම්බන්ධ වූ විට, ඔබ බ්‍රව්සරයක් භාවිතා කරයි. ඉන්ටර්නෙට් එක්ස්ප්ලෝරර්, ක්‍රෝම්, ෆයර්ෆොක්ස් සහ සෆාරි ඔබ දන්නා උදාහරණ වේ. බ්‍රව්සරයට ජාවාස්ක්‍රිප්ට් තේරුම් ගත හැකි අතර එය කළ යුතු දේ පරිගණකයට කියන්න. ජාවාස්ක්‍රිප්ට් උපදෙස් ශ්‍රිත ලෙස හැඳින්වේ.

ක්‍රියාකාරිත්වය: ජාවාස්ක්‍රිප්ට් හි ශ්‍රිතයක් කර්මාන්ත ශාලාවක් වැනි ය. එය ඇතුළත එක් යන්ත්‍රයක් පමණක් ඇති කුඩා කර්මාන්ත ශාලාවක් විය හැකිය. නැතහොත් එහි තවත් බොහෝ කුඩා කර්මාන්තශාලා අඩංගු විය හැකිය. සැබෑ ජීවිත ඇඳුම් කර්මාන්ත ශාලාවක ඔබට රෙදි සහ බොබින් නූල් ඇතුලට ගොස් ටී-ෂර්ට් සහ ජීන්ස් එළියට එනු ඇත. අපගේ ජාවාස්ක්‍රිප්ට් කර්මාන්ත ශාලාව දත්ත සැකසීම පමණක් සිදු කරයි, එයට මැසීමට, සිදුරක් හෑරීමට හෝ ලෝහ උණු කිරීමට නොහැකිය. අපගේ ජාවාස්ක්‍රිප්ට් කර්මාන්තශාලාවේ දත්ත ඇතුළට ගොස් දත්ත එළියට එයි.

මෙම සියලු දත්ත දේවල් තරමක් කම්මැලි බවක් පෙනේ, නමුත් එය ඇත්තෙන්ම ඉතා සිසිල් ය; රොබෝවෙකුට රාත්‍රී ආහාරය සඳහා කුමක් කළ යුතු දැයි පවසන ශ්‍රිතයක් අපට තිබිය හැකිය. මම ඔබට සහ ඔබේ මිතුරාට මගේ නිවසට ආරාධනා කරමි. ඔබ කුකුළු මස් කකුල් වලට වඩාත්ම කැමතියි, මම සොසේජස් වලට කැමතියි, ඔබේ මිතුරාට සැමවිටම ඔබට අවශ්‍ය දේ අවශ්‍ය වන අතර මගේ මිතුරා මස් කන්නේ නැත.

මට සාප්පු යෑමට වෙලාවක් නැත, එබැවින් තීරණ ගැනීමට අපට ශීතකරණයේ ඇති දේ දැන ගැනීමට ශ්‍රිතයට අවශ්‍ය වේ. සෑම අමුද්‍රව්‍යයකටම වෙනස් ආහාර පිසීමේ කාලයක් ඇති අතර සෑම දෙයක්ම එකවර රොබෝවරයා විසින් උණුසුම්ව ලබා දීමට අපට අවශ්‍යය. අප කැමති දේ පිළිබඳ දත්ත සමඟ ශ්‍රිතය සැපයිය යුතුය, ශ්‍රිතයට ශීතකරණයේ 'කතා' කළ හැකි අතර ශ්‍රිතයට රොබෝව පාලනය කළ හැකිය.

ශ්‍රිතයකට සාමාන්‍යයෙන් නමක්, වරහන් සහ වරහන් ඇත. මෙවැනි:

function cookMeal() {  /*  STUFF INSIDE THE FUNCTION  */  }

සටහන බව /*...*/හා //නැවතුම් කේතය බ්රව්සරය විසින් කියවනු ලබනවා.

නම: ඔබට අවශ්‍ය ඕනෑම වචනයක් ගැන ඔබට ශ්‍රිතයක් ඇමතිය හැකිය. "කුක්මීල්" උදාහරණය වචන දෙකක් එකට සම්බන්ධ කිරීම සහ දෙවැන්න ආරම්භයේ දී ලොකු අකුරක් ලබා දීම සාමාන්‍ය දෙයකි - නමුත් මෙය අවශ්‍ය නොවේ. එයට එහි ඉඩක් තිබිය නොහැකි අතර එය තනිවම සංඛ්‍යාවක් විය නොහැක.

වරෙන්තු: "වරහන්" හෝ ()ජාවාස්ක්‍රිප්ට් ක්‍රියාකාරී කර්මාන්තශාලාවේ දොරේ ඇති අකුරු කොටුව හෝ කර්මාන්තශාලාවට තොරතුරු පැකට් යැවීම සඳහා වීථියේ තැපැල් පෙට්ටියක් වේ. සමහර විට postbox සලකුණු කළ හැකි උදාහරණයක් ලෙස cookMeal(you, me, yourFriend, myFriend, fridge, dinnerTime) , ඔබ එය දිය යුතු දේ දත්ත දන්නවා අවස්ථාවක,.

බ්රේස්: මේ වගේ පෙනෙන "වරහන්" {}අපේ කර්මාන්ත ශාලාවේ පැහැපත් කවුළු. කර්මාන්තශාලාවේ ඇතුළත සිට ඔබට පිටත දැකිය හැකිය, නමුත් පිටතින් ඔබට ඇතුළට නොපෙනේ.

ඉහත දීර් ON කේත උදාහරණය

අපගේ කේතය ආරම්භ වන්නේ වචන ශ්‍රිතයෙනි , එබැවින් එය එකක් බව අපි දනිමු! එවිට ශ්‍රිතයේ නම ගායනා කරන්න - එය ශ්‍රිතය ගැන මගේම විස්තරයකි. ඉන්පසු වරහන් () . වරහන් වර්‍ගයක් සැමවිටම පවතී. සමහර විට ඒවා හිස් ය, සමහර විට ඒවායේ යමක් තිබේ. මේ තැනැත්තාට වචනයක් ඇත : (person). මෙයින් පසු මේ ආකාරයේ වරහනක් {ඇත. මෙය ගායනයේ () ශ්‍රිතයේ ආරම්භය සනිටුහන් කරයි . එය වන ලකුණු හවුල්කරුවෙකු අවසන් කර ගී ගයති () මේ වගේ}

function sing(person) {  /* STUFF INSIDE THE FUNCTION */  }

එබැවින් මෙම ශ්‍රිතයට ගායනයට යම් සම්බන්ධයක් තිබිය හැකි අතර පුද්ගලයෙකු පිළිබඳ යම් දත්ත අවශ්‍ය විය හැකිය. එම දත්ත සමඟ යමක් කිරීමට එහි ඇතුළත උපදෙස් ඇත.

දැන්, ගායනය () ශ්‍රිතයෙන් පසුව , කේතයේ අවසානය අසල රේඛාව ඇත

var person="an old lady";

විචල්‍ය: var යන අකුරු "විචල්ය" යන්නෙන් දැක්වේ. විචල්යයක් ලියුම් කවරයක් වැනි ය. පිටතින් මෙම ලියුම් කවරය "පුද්ගලයා" ලෙස සලකුණු කර ඇත. එහි ඇතුළත අපගේ ක්‍රියාකාරිත්වයට අවශ්‍ය තොරතුරු සහිත කඩදාසි පෙත්තක් අඩංගු වේ, සමහර අකුරු හා අවකාශයන් නූල් කැබැල්ලක් මෙන් එකට එකතු වී ඇත (එය නූලක් ලෙස හැඳින්වේ) එය "මහලු කාන්තාවක්" කියවන වාක්‍ය ඛණ්ඩයක් සාදයි. අපගේ ලියුම් කවරයේ සංඛ්‍යා (නිඛිල ලෙස හැඳින්වේ), උපදෙස් (ශ්‍රිත ලෙස හැඳින්වේ), ලැයිස්තු ( අරා ලෙස හැඳින්වේ ) වැනි වෙනත් දේ අඩංගු විය හැකිය . මෙම විචල්‍යය සියලුම වරහන් වලින් පිටත ලියා ඇති {}නිසාත්, ඔබ වරහන් තුළ සිටින විට පැහැපත් කවුළු හරහා දැකිය හැකි නිසාත්, මෙම විචල්‍යය කේතයේ ඕනෑම තැනක සිට දැකිය හැකිය. අපි මෙය 'ගෝලීය විචල්‍යය' ලෙස හඳුන්වමු.

ග්ෙලෝබල් විචල්ය: පුද්ගලයා ගෝලීය විචල්ය වන අතර, ඔබ "තරුණ වියේ" වෙත "පරණ කාන්තාව" සිට එහි අගය වෙනස් නම්, එහි තේරුම පුද්ගලයා ඔබ එය නැවත වෙනත් ඕනෑම උත්සවයකදී එය වෙනස් කිරීමට තීරණය කරන තුරු තරුණයා වීම තබා ඇත කේතයට එය තරුණයෙක් බව පෙනේ. මුද්රිත මාධ්ය F12ද විකල්ප සැකසුම් දී බ්රවුසරයේ Developer Console විවෘත මෙම අගය දේ බලන්න "පුද්ගලයා" ටයිප් කිරීමට බොත්තම හෝ පෙනුම. ටයිප් person="a young man"එය වෙනස් පසුව එය වෙනස් කර ඇති බව දැක ගැනීමට "පුද්ගලයා" ටයිප් නැවත වරක්.

මෙයින් පසු අපට රේඛාව තිබේ

sing(person);

මෙම රේඛාව ශ්‍රිතය අමතන්නේ එය බල්ලෙකු ලෙස හඳුන්වන ආකාරයට ය

"එන්න ගායනා කරන්න , ඇවිත් පුද්ගලයෙකුව ගන්න !"

බ්‍රව්සරය ජාවාස්ක්‍රිප්ට් කේතය මෙම රේඛාවට ලඟා වූ විට, එය ක්‍රියාකාරීත්වය ආරම්භ කරයි. බ්‍රව්සරයට එය ක්‍රියාත්මක කිරීමට අවශ්‍ය සියලු තොරතුරු ඇති බව තහවුරු කර ගැනීම සඳහා මම රේඛාව අවසානයේ තැබුවෙමි.

කාර්යයන් ක්‍රියාවන් අර්ථ දක්වයි - ප්‍රධාන කාර්යය වන්නේ ගායනයයි. එය නමින් විචල්ය අඩංගු firstPart ගීතය පද එක් එක් අදාළ වන බව එම පුද්ගලයා ගැන ගී ගයන අදාළ වන: "තියෙනවා" + පුද්ගලයා + "ගිල සිටි". ඔබ පළමු කොටස කොන්සෝලය තුළට ටයිප් කළහොත් , ඔබට ශ්‍රිතයක් තුළ විචල්‍යය අගුළු දමා ඇති බැවින් ඔබට පිළිතුරක් නොලැබේ - වරහන් වල පැහැපත් කවුළු තුළ බ්‍රව්සරයට නොපෙනේ.

වසා දැමීම්: වසා දැමීම් යනු විශාල ගායන () ශ්‍රිතය තුළ ඇති කුඩා කාර්යයන් වේ. විශාල කර්මාන්ත ශාලාව තුළ ඇති කුඩා කර්මාන්තශාලා. ඔවුන් සෑම කෙනෙකුම තමන්ගේම වරහන් ඇති අතර එයින් අදහස් කරන්නේ ඔවුන් තුළ ඇති විචල්‍යයන් පිටතින් දැකිය නොහැකි බවයි. වසා දැමීම් වලදී විචල්‍යයන්ගේ නම් ( සත්වයා සහ ප්‍රති result ලය ) නැවත නැවතත් කළ හැකි නමුත් විවිධ අගයන් ඇත. ඔබ මෙම විචල්‍ය නම් කොන්සෝල කවුළුව තුළ ටයිප් කළහොත් ඔබට එහි වටිනාකම ලැබෙන්නේ එය ස්ථර දෙකකින් සැඟවී ඇති බැවිනි.

වසා දැමීම් සියල්ලෝම දනිති සිං () ශ්‍රිතයේ විචල්‍යය ෆස්ට්පාර්ට් ලෙස හැඳින්වේ , මන්ද යත් ඒවායේ පැහැයෙන් යුත් කවුළු වලින් දැකගත හැකි බැවිනි.

වසා දැමීමෙන් පසු රේඛා පැමිණේ

fly();
spider();
bird();
cat();

සිං () ශ්‍රිතය මෙම එක් එක් ශ්‍රිතයට ලබා දී ඇති අනුපිළිවෙලට කැඳවනු ඇත. එවිට ගායන () ශ්‍රිතයේ වැඩ කටයුතු සිදු කෙරේ.


56

හරි, අවුරුදු 6 ක දරුවෙකු සමඟ කතා කිරීම, මම සමහරවිට පහත සඳහන් ආශ්‍රයන් භාවිතා කරමි.

සිතන්න - ඔබ මුළු නිවසේම ඔබේ කුඩා සහෝදර සහෝදරියන් සමඟ සෙල්ලම් කරන අතර, ඔබ ඔබේ සෙල්ලම් බඩු සමඟ එහාට මෙහාට යමින් ඔවුන්ගෙන් සමහරක් ඔබේ වැඩිමහල් සහෝදරයාගේ කාමරයට ගෙන එනු ලැබේ. ටික වේලාවකට පසු ඔබේ සහෝදරයා පාසලෙන් ආපසු පැමිණ ඔහුගේ කාමරයට ගිය අතර ඔහු එය තුළට අගුලු දමා ඇති බැවින් දැන් ඔබට එහි දමා ඇති සෙල්ලම් බඩු වලට සෘජු ආකාරයකින් ප්‍රවේශ විය නොහැක. නමුත් ඔබට දොරට තට්ටු කර ඔබේ සහෝදරයාගෙන් එම සෙල්ලම් බඩු ඉල්ලන්න. මෙය සෙල්ලම් බඩු වැසීම ලෙස හැඳින්වේ ; ඔබේ සහෝදරයා එය ඔබ වෙනුවෙන්ම සාදා ඇති අතර ඔහු දැන් බාහිර විෂය පථයට පැමිණ ඇත.

කෙටුම්පතකින් දොරක් අගුළු දමා ඇති අතර, කිසිවෙකු එහි නොසිටින විට (සාමාන්‍ය ක්‍රියාකාරිත්වය ක්‍රියාත්මක කිරීම), පසුව යම් දේශීය ගින්නක් ඇති වී කාමරය ගිනිබත් කරයි (කසළ එකතු කරන්නා: ඩී), පසුව නව කාමරයක් ඉදිකර ඇති අතර දැන් ඔබට පිටව යා හැකිය එහි තවත් සෙල්ලම් බඩු (නව ක්‍රියාකාරී උදාහරණය), නමුත් පළමු කාමරයේ ඉතිරි වූ සෙල්ලම් බඩු කිසි විටෙකත් ලබා නොගන්න.

උසස් දරුවෙකු සඳහා මම පහත සඳහන් දේ ඉදිරිපත් කරමි. එය පරිපූර්ණ නොවේ, නමුත් එය කුමක්ද යන්න පිළිබඳව ඔබට හැඟීමක් ඇති කරයි:

function playingInBrothersRoom (withToys) {
  // We closure toys which we played in the brother's room. When he come back and lock the door
  // your brother is supposed to be into the outer [[scope]] object now. Thanks god you could communicate with him.
  var closureToys = withToys || [],
      returnToy, countIt, toy; // Just another closure helpers, for brother's inner use.

  var brotherGivesToyBack = function (toy) {
    // New request. There is not yet closureToys on brother's hand yet. Give him a time.
    returnToy = null;
    if (toy && closureToys.length > 0) { // If we ask for a specific toy, the brother is going to search for it.

      for ( countIt = closureToys.length; countIt; countIt--) {
        if (closureToys[countIt - 1] == toy) {
          returnToy = 'Take your ' + closureToys.splice(countIt - 1, 1) + ', little boy!';
          break;
        }
      }
      returnToy = returnToy || 'Hey, I could not find any ' + toy + ' here. Look for it in another room.';
    }
    else if (closureToys.length > 0) { // Otherwise, just give back everything he has in the room.
      returnToy = 'Behold! ' + closureToys.join(', ') + '.';
      closureToys = [];
    }
    else {
      returnToy = 'Hey, lil shrimp, I gave you everything!';
    }
    console.log(returnToy);
  }
  return brotherGivesToyBack;
}
// You are playing in the house, including the brother's room.
var toys = ['teddybear', 'car', 'jumpingrope'],
    askBrotherForClosuredToy = playingInBrothersRoom(toys);

// The door is locked, and the brother came from the school. You could not cheat and take it out directly.
console.log(askBrotherForClosuredToy.closureToys); // Undefined

// But you could ask your brother politely, to give it back.
askBrotherForClosuredToy('teddybear'); // Hooray, here it is, teddybear
askBrotherForClosuredToy('ball'); // The brother would not be able to find it.
askBrotherForClosuredToy(); // The brother gives you all the rest
askBrotherForClosuredToy(); // Nothing left in there

ඔබට පෙනෙන පරිදි, කාමරයේ ඉතිරිව ඇති සෙල්ලම් බඩු තවමත් සහෝදරයා හරහා ලබා ගත හැකි අතර කාමරය අගුළු දමා තිබේ නම් කමක් නැත. මෙන්න එය සමඟ සෙල්ලම් කිරීමට jsbin .


49

අවුරුදු හයක් වයසැති දරුවෙකුට පිළිතුරක් (ශ්‍රිතයක් යනු කුමක්ද සහ විචල්‍යය යනු කුමක්ද සහ දත්ත යනු කුමක්දැයි ඔහු දන්නා බව උපකල්පනය කිරීම):

කාර්යයන් මඟින් දත්ත ආපසු ලබා දිය හැකිය. ශ්‍රිතයකින් ඔබට ආපසු යා හැකි එක් ආකාරයක දත්ත තවත් ශ්‍රිතයකි. එම නව ශ්‍රිතය නැවත ලැබුණු විට, එය නිර්මාණය කළ ශ්‍රිතයේ භාවිතා වන සියලුම විචල්‍යයන් සහ තර්ක පහව යන්නේ නැත. ඒ වෙනුවට, එම දෙමාපිය කාර්යය "වසා දමයි." වෙනත් වචන වලින් කිවහොත්, එහි ඇතුළත බැලීමට හා එය ආපසු ලබා දුන් ශ්‍රිතය හැර එය භාවිතා කළ විචල්‍යයන් දැකිය නොහැක. එම නව ශ්‍රිතයට එය නිර්මාණය කළ ශ්‍රිතය තුළට ආපසු හැරී බැලීමට සහ එහි ඇතුළත දත්ත බැලීමට විශේෂ හැකියාවක් ඇත.

function the_closure() {
  var x = 4;
  return function () {
    return x; // Here, we look back inside the_closure for the value of x
  }
}

var myFn = the_closure();
myFn(); //=> 4

එය පැහැදිලි කිරීමට තවත් සරල ක්‍රමයක් වන්නේ විෂය පථය අනුව ය:

ඔබ විශාල විෂය පථයක් තුළ කුඩා විෂය පථයක් නිර්මාණය කරන ඕනෑම වේලාවක, කුඩා විෂය පථයට සෑම විටම විශාල විෂය පථයේ ඇති දේ දැකගත හැකිය.


49

ජාවාස්ක්‍රිප්ට් හි ශ්‍රිතයක් යනු හුදෙක් උපදෙස් මාලාවකට (සී භාෂාවෙන් මෙන්) යොමු කිරීමක් පමණක් නොව, එය භාවිතා කරන සියලුම ස්ථානීය නොවන විචල්‍යයන් (ග්‍රහණය කරන ලද විචල්‍යයන්) සඳහා යොමු කිරීම් වලින් සමන්විත සැඟවුණු දත්ත ව්‍යුහයක් ද එයට ඇතුළත් ය. එවැනි කොටස් දෙකක කාර්යයන් වසා දැමීම් ලෙස හැඳින්වේ. JavaScript හි සෑම කාර්යයක්ම වසා දැමීමක් ලෙස සැලකිය හැකිය.

වසා දැමීම් යනු රාජ්යයක් සමඟ ක්රියා කරයි. එය "මෙය" ට තරමක් සමාන වන අතර "මෙය" ශ්‍රිතයක් සඳහා ක්‍රියාකාරීත්වයක් සපයන නමුත් ක්‍රියාකාරීත්වය සහ "මෙය" වෙනම වස්තු වේ ("මෙය" යනු මන ancy කල්පිත පරාමිතියක් වන අතර එය ස්ථිරවම බන්ධනය කිරීමට ඇති එකම ක්‍රමය a කාර්යය වන්නේ වසා දැමීමක් නිර්මාණය කිරීමයි). "මෙය" සහ ශ්‍රිතය සැමවිටම වෙන වෙනම ජීවත්වන අතර, ශ්‍රිතයක් එහි වසා දැමීමෙන් වෙන් කළ නොහැකි අතර අල්ලා ගත් විචල්‍යයන්ට ප්‍රවේශ වීමට භාෂාව කිසිදු ක්‍රමයක් සපයන්නේ නැත.

මන්දයත්, මෙම බාහිර විචල්‍යයන් සියල්ලම වාචිකව කැදැලි කරන ලද ශ්‍රිතයක දාමයේ දේශීය විචල්‍යයන් වන නිසා (ගෝලීය විචල්‍යයන් යම් මූල ශ්‍රිතයක දේශීය විචල්‍යයන් ලෙස උපකල්පනය කළ හැකිය), සහ ශ්‍රිතයක සෑම ක්‍රියාවක්ම නව අවස්ථා නිර්මාණය කරයි එහි දේශීය විචල්‍යයන් අනුව, එය අනුගමනය කරන්නේ ශ්‍රිතයක් නැවත ක්‍රියාත්මක කිරීම (හෝ එය නැවත කැඳවීමක් ලෙස ලියාපදිංචි කිරීම වැනි වෙනත් ආකාරයකින් මාරු කිරීම) කැදැලි ශ්‍රිතයක් නව වසා දැමීමක් නිර්මාණය කරයි (එහි ක්‍රියාත්මක විය හැකි අද්විතීය යොමු කරන ලද නොලෝකල් විචල්‍යයන් සමූහයකි. සන්දර්භය).

එසේම, ජාවාස්ක්‍රිප්ට් හි දේශීය විචල්‍යයන් නිර්මාණය වී ඇත්තේ තොග රාමුව මත නොව ගොඩවල් මත වන අතර විනාශ වන්නේ කිසිවෙකු ඒවා යොමු නොකරන විට පමණි. ශ්‍රිතයක් නැවත පැමිණෙන විට, එහි දේශීය විචල්‍යයන් පිළිබඳ යොමු කිරීම් අඩු වේ, නමුත් වර්තමාන ක්‍රියාත්මක කිරීමේදී ඒවා වසා දැමීමේ කොටසක් බවට පත්වී එහි ශබ්දකෝෂ කැදැලි ශ්‍රිතයන් විසින් තවමත් යොමු කරනු ලැබුවහොත් ඒවා තවමත් අහෝසි විය හැකිය (එය සිදුවිය හැක්කේ යොමු දැක්වීම් කළහොත් පමණි මෙම කැදැලි කාර්යයන් නැවත ලබා දෙන ලදි හෝ වෙනත් බාහිර කේතයකට මාරු කරන ලදි).

උදාහරණයක්:

function foo (initValue) {
   //This variable is not destroyed when the foo function exits.
   //It is 'captured' by the two nested functions returned below.
   var value = initValue;

   //Note that the two returned functions are created right now.
   //If the foo function is called again, it will return
   //new functions referencing a different 'value' variable.
   return {
       getValue: function () { return value; },
       setValue: function (newValue) { value = newValue; }
   }
}

function bar () {
    //foo sets its local variable 'value' to 5 and returns an object with
    //two functions still referencing that local variable
    var obj = foo(5);

    //Extracting functions just to show that no 'this' is involved here
    var getValue = obj.getValue;
    var setValue = obj.setValue;

    alert(getValue()); //Displays 5
    setValue(10);
    alert(getValue()); //Displays 10

    //At this point getValue and setValue functions are destroyed
    //(in reality they are destroyed at the next iteration of the garbage collector).
    //The local variable 'value' in the foo is no longer referenced by
    //anything and is destroyed too.
}

bar();

47

සමහර විට සියල්ලෙන් මඳක් ඔබ්බට අවුරුදු හයක් වයසැති ළමයින් අතරින්, නමුත් ජාවාස්ක්‍රිප්ට් හි වසා දැමීමේ සංකල්පය මා සඳහා ක්ලික් කිරීමට උපකාරී වූ උදාහරණ කිහිපයක්.

වසා දැමීම යනු වෙනත් ශ්‍රිතයක විෂය පථයට (එහි විචල්‍යයන් සහ ශ්‍රිත) ප්‍රවේශය ඇති ශ්‍රිතයකි. වසා දැමීමක් නිර්මාණය කිරීමට පහසුම ක්‍රමය වන්නේ ශ්‍රිතයක් තුළ ඇති ශ්‍රිතයක් සමඟ ය; හේතුව, ජාවාස්ක්‍රිප්ට් හි ශ්‍රිතයකට සෑම විටම එහි අඩංගු ශ්‍රිතයේ විෂය පථයට ප්‍රවේශය තිබීමයි.

function outerFunction() {
    var outerVar = "monkey";
    
    function innerFunction() {
        alert(outerVar);
    }
    
    innerFunction();
}

outerFunction();

වඳුරා

ඉහත උදාහරණයේ දී, පිටත ක්‍රියාකාරිත්වය හැඳින්වෙන්නේ අභ්‍යන්තර ක්‍රියාකාරිත්වය ලෙසිනි. පිටත ක්‍රියාකාරීත්වය අභ්‍යන්තර ක්‍රියාකාරීත්වයට ලබා ගත හැකි ආකාරය සැලකිල්ලට ගන්න.

දැන් පහත සඳහන් කරුණු සලකා බලන්න:

function outerFunction() {
    var outerVar = "monkey";
    
    function innerFunction() {
        return outerVar;
    }
    
    return innerFunction;
}

var referenceToInnerFunction = outerFunction();
alert(referenceToInnerFunction());

වඳුරා

referenceToInnerFunction පිටත ක්‍රියාකාරිත්වය () ලෙස සකසා ඇති අතර එය හුදෙක් අභ්‍යන්තර ක්‍රියාකාරිත්වයට යොමු කරයි. ReferenceToInnerFunction යනුවෙන් හැඳින්වෙන විට, එය පිටතවර් නැවත ලබා දෙයි. නැවතත්, ඉහත පරිදි, මෙයින් පෙන්නුම් කරන්නේ අභ්‍යන්තර ක්‍රියාකාරිත්වයට පිටත ක්‍රියාකාරීත්වයේ විචල්‍යයක් වන පිටත ක්‍රියාකාරීත්වයට ප්‍රවේශයක් ඇති බවයි. තවද, පිටත ක්‍රියාකාරිත්වය ක්‍රියාත්මක කිරීමෙන් පසුව පවා එය මෙම ප්‍රවේශය රඳවා තබා ගැනීම සිත්ගන්නා කරුණකි.

දේවල් රසවත් වන තැන මෙන්න. අපි පිටත ක්‍රියාකාරිත්වයෙන් මිදීමට නම්, එය ශුන්‍ය ලෙස සකසන්න යැයි කියන්න, යොමු ටෝඉන්නර්ෆන්ෂන් පිටත වෝරයේ වටිනාකමට ප්‍රවේශ වීම නැති කරයි යැයි ඔබ සිතනු ඇත. නමුත් මෙය එසේ නොවේ.

function outerFunction() {
    var outerVar = "monkey";
    
    function innerFunction() {
        return outerVar;
    }
    
    return innerFunction;
}

var referenceToInnerFunction = outerFunction();
alert(referenceToInnerFunction());

outerFunction = null;
alert(referenceToInnerFunction());

ALERT: වඳුරා ALERT: වඳුරා

නමුත් මෙය එසේ වන්නේ කෙසේද? පිටත ක්‍රියාකාරිත්වය ශුන්‍ය ලෙස සකසා ඇති යොමු ටෝඉන්නර්ෆන්ෂන් තවමත් පිටත වර් වල වටිනාකම දැන ගන්නේ කෙසේද?

ReferenceToInnerFunction හට තවමත් පිටත වර් වල වටිනාකමට ප්‍රවේශ විය හැකි හේතුව නම්, පිටත ක්‍රියාකාරිත්වය තුළ අභ්‍යන්තර ක්‍රියාකාරිත්වය ස්ථානගත කිරීමෙන් වසා දැමීම ප්‍රථම වරට නිර්මාණය කළ විට, අභ්‍යන්තර ක්‍රියාකාරිත්වය පිටත විෂය පථයේ විෂය පථයට (එහි විචල්‍යයන් සහ ක්‍රියාකාරකම්) එහි විෂය පථයට යොමු කිරීමක් එක් කළ බැවිනි. මෙයින් අදහස් කරන්නේ පිටත ක්‍රියාකාරීත්වය ඇතුළුව පිටත ක්‍රියාකාරීත්වයේ විචල්‍යයන් සියල්ලටම අභ්‍යන්තර ක්‍රියාකාරීත්වයට දර්ශකයක් හෝ යොමු කිරීමක් ඇති බවයි. එබැවින් පිටත ක්‍රියාකාරිත්වය ක්‍රියාත්මක වීම අවසන් වූ විට හෝ එය මකාදැමූ විට හෝ ශුන්‍ය ලෙස සකසා තිබුණද, පිටත පරාසය වැනි එහි විෂය පථයේ විචල්‍යයන් මතකයේ රැඳෙන්නේ ඒවා අභ්‍යන්තර ක්‍රියාකාරිත්වයේ කැපී පෙනෙන සඳහනක් නිසා ය. referenceToInnerFunction. පිටත වෝරය සහ පිටත ක්‍රියාකාරීත්වයේ විචල්‍යයන් මතකයෙන් සැබවින්ම මුදා හැරීම සඳහා ඔබට මෙම කැපී පෙනෙන සඳහනෙන් මිදීමට සිදුවේ.

//////////

සැලකිල්ලට ගත යුතු වසා දැමීම් පිළිබඳ තවත් කරුණු දෙකක්. පළමුව, වසා දැමීම සැමවිටම එහි අඩංගු ක්‍රියාකාරිත්වයේ අවසාන අගයන් වෙත ප්‍රවේශය ඇත.

function outerFunction() {
    var outerVar = "monkey";
    
    function innerFunction() {
        alert(outerVar);
    }
    
    outerVar = "gorilla";

    innerFunction();
}

outerFunction();

ගෝරිල්ලා

දෙවනුව, වසා දැමීමක් නිර්මාණය කළ විට, එය එහි ඇති සියලුම ශ්‍රිත විචල්‍යයන් හා ශ්‍රිතයන් වෙත යොමු කිරීමක් රඳවා ගනී; එය තෝරා ගැනීමට සහ තෝරා ගැනීමට නොලැබේ. එහෙත්, එසේ නම්, වසා දැමීම් අරපිරිමැස්මෙන් හෝ අවම වශයෙන් ප්‍රවේශමෙන් භාවිතා කළ යුතුය. අඩංගු ශ්‍රිතයක් ක්‍රියාත්මක කිරීමෙන් පසු බොහෝ විචල්‍යයන් මතකයේ තබා ගත හැකිය.


45

මම ඒවා මොසිල්ලා වැසීම් පිටුවට යොමු කරමි . වසා දැමීමේ මූලික කරුණු සහ ප්‍රායෝගික භාවිතය පිළිබඳ හොඳම, වඩාත්ම සංක්ෂිප්ත හා සරල පැහැදිලි කිරීම එයයි. ජාවාස්ක්‍රිප්ට් ඉගෙන ගන්නා ඕනෑම කෙනෙකුට එය බෙහෙවින් නිර්දේශ කෙරේ.

ඔව්, මම එය අවුරුදු 6 ක දරුවෙකුට පවා නිර්දේශ කරමි - 6 හැවිරිදි දරුවා වසා දැමීම් ගැන ඉගෙන ගන්නේ නම්, ඔවුන් ලිපියේ දක්වා ඇති සංක්ෂිප්ත හා සරල පැහැදිලි කිරීම වටහා ගැනීමට ඔවුන් සූදානම්ය .


මම එකඟ වෙමි: ඉහත සඳහන් මොසිල්ලා පිටුව විශේෂයෙන් සරල හා සංක්ෂිප්ත ය. පුදුමයට කරුණක් නම්, ඔබගේ පෝස්ට් අනෙක් ඒවා තරම් පුළුල් ලෙස අගය නොකිරීමයි.
බ්‍රයිස් කොස්ටිලස්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.