0Pricing
R Academy · บทเรียน

ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่

แยกความแตกต่างระหว่าง .GlobalEnv, environment ของฟังก์ชัน และคลอสเชอร์

ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่ เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

ตัวแปรเฉพาะที่ในฟังก์ชัน

ตัวแปรที่กำหนดด้วย <- หรือ = ภายในส่วนเนื้อหาของฟังก์ชันจะเป็นตัวแปรเฉพาะที่ของฟังก์ชันนั้น ตัวแปรเหล่านี้ถูกสร้างในสภาพแวดล้อมของฟังก์ชันเองและหายไปเมื่อฟังก์ชันส่งคืนค่า โดยจะไม่ส่งผลต่อขอบเขตของผู้เรียกใช้

x <- 'global'
f <- function() {
  x <- 'local'   # creates a new local binding, does not modify global x
  cat('Inside f: x =', x, '\n')
}
f()
cat('Outside f: x =', x, '\n')  # still 'global'

พารามิเตอร์ฟังก์ชันเป็นตัวแปรเฉพาะที่

พารามิเตอร์ฟังก์ชันก็เป็นตัวแปรเฉพาะที่เช่นกัน การแก้ไขพารามิเตอร์ภายในฟังก์ชันจะไม่ส่งผลต่ออาร์กิวเมนต์ในสภาพแวดล้อมของผู้เรียกใช้ R ส่งอาร์กิวเมนต์ด้วยค่า (โดยมีการคัดลอกเมื่อแก้ไข)

double_it <- function(n) {
  n <- n * 2      # modifies local copy only
  cat('Inside:', n, '\n')
}
my_n <- 5
double_it(my_n)
cat('Outside:', my_n, '\n')  # still 5

<<- สำหรับการกำหนดค่าในส่วนกลาง

<<- (การกำหนดค่าเหนือสภาพแวดล้อม) จะค้นหาขึ้นไปตามสายโซ่สภาพแวดล้อมแม่ และกำหนดค่าให้กับการจับคู่แรกที่พบ หากไม่พบการจับคู่ที่ใดเลย จะสร้างการผูกชื่อในสภาพแวดล้อมส่วนกลาง ควรใช้เท่าที่จำเป็น เพราะการใช้ <<- มากเกินไปทำให้เข้าใจการทำงานของฟังก์ชันได้ยาก

total <- 0
add_to_total <- function(x) {
  total <<- total + x
}
add_to_total(10)
add_to_total(25)
add_to_total(5)
cat('Total:', total, '\n')

<<- ค้นหาขึ้นไปตามสายโซ่

<<- ไม่ได้กำหนดค่าให้กับสภาพแวดล้อมส่วนกลางโดยทันที แต่จะไล่ขึ้นไปตามสายโซ่สภาพแวดล้อมแม่ และกำหนดค่าให้กับสภาพแวดล้อมแรกที่มีชื่อนั้นอยู่ หากตัวแปรมีอยู่ในฟังก์ชันที่ครอบอยู่ ตัวแปรในฟังก์ชันนั้นจะถูกอัปเดต

outer <- function() {
  n <- 0
  increment <- function() n <<- n + 1
  increment()
  increment()
  cat('n in outer:', n, '\n')  # n was in outer's env, updated there
}
outer()
# n does NOT appear in global env
cat('n in global:', exists('n', envir = globalenv()), '\n')

assign() สำหรับระบุสภาพแวดล้อมเป้าหมายอย่างชัดเจน

assign('name', value, envir = e) กำหนดค่าให้กับสภาพแวดล้อมที่ระบุโดยตรง ชัดเจนกว่า <<- และมีประโยชน์เมื่อคุณมีออบเจ็กต์สภาพแวดล้อมและต้องการกำหนดค่าให้ตำแหน่งนั้นโดยเฉพาะ

my_env <- new.env(parent = emptyenv())
assign('score', 95, envir = my_env)
assign('name', 'Alice', envir = my_env)
cat('score:', get('score', envir = my_env), '\n')
cat('name :', get('name',  envir = my_env), '\n')

local() — บล็อกโค้ดที่แยกออกจากกัน

local({...}) ประเมินนิพจน์ในสภาพแวดล้อมเฉพาะที่ใหม่ ตัวแปรที่สร้างภายในบล็อกจะไม่รั่วไหลไปยังสภาพแวดล้อมส่วนกลาง เหมาะสำหรับการคำนวณชั่วคราวที่ไม่ควรทำให้พื้นที่ทำงานปะปน

result <- local({
  temp1 <- 100
  temp2 <- 200
  temp1 + temp2   # the last expression is returned
})
cat('result:', result, '\n')
cat('temp1 in global:', exists('temp1'), '\n')  # FALSE

local() กับฟังก์ชันสำหรับการแยกขอบเขต

ทั้ง local() และฟังก์ชันที่ถูกเรียกใช้ทันทีช่วยแยกขอบเขตได้ local() กระชับกว่าเมื่อใช้แยกขอบเขตเพียงครั้งเดียว ส่วนฟังก์ชันที่ตั้งชื่อเหมาะกว่าเมื่อคุณต้องการนำตรรกะกลับมาใช้ซ้ำหรือนำไปทดสอบ

# Option A: local()
result_a <- local({
  x <- 7
  y <- 3
  x * y
})
# Option B: immediately invoked function
result_b <- (function() {
  x <- 7
  y <- 3
  x * y
})()
cat(result_a, result_b, '\n')
cat('x in global:', exists('x'), '\n')

การอ่านตัวแปรส่วนกลางจากฟังก์ชัน

ฟังก์ชันสามารถอ่านตัวแปรจากขอบเขตที่ครอบอยู่ (ไม่ว่าจะเป็นส่วนกลางหรือขอบเขตอื่น) ได้โดยไม่ต้องใช้รูปแบบพิเศษ นี่เป็นการกำหนดขอบเขตแบบเลกซิคัลตามปกติ อย่างไรก็ตาม การพึ่งพาสถานะส่วนกลางมากเกินไปทำให้ทดสอบฟังก์ชันได้ยาก จึงควรใช้อาร์กิวเมนต์ที่ระบุอย่างชัดเจนเมื่อทำได้

tax_rate <- 0.20   # global configuration
apply_tax <- function(price) {
  price * (1 + tax_rate)  # reads tax_rate from global
}
cat(apply_tax(100), '\n')
cat(apply_tax(250), '\n')

การบดบังชื่อตัวแปร

เมื่อตัวแปรเฉพาะที่มีชื่อเดียวกับตัวแปรส่วนกลาง การผูกชื่อเฉพาะที่จะบดบังตัวแปรส่วนกลาง ภายในฟังก์ชันจะใช้ตัวแปรเฉพาะที่ ส่วนกลางจะไม่ถูกเปลี่ยนแปลง หากเกิดขึ้นโดยไม่ตั้งใจ อาจทำให้เกิดข้อผิดพลาดที่สังเกตได้ยาก

mean <- 99   # shadows base R's mean() function
cat(mean, '\n')   # prints 99, not the function
# To call the real mean, use base:: prefix
cat(base::mean(c(1, 2, 3, 4, 5)), '\n')
rm(mean)   # remove the shadow

สภาพแวดล้อมของ function()

ทุกครั้งที่เรียกใช้ฟังก์ชัน R จะสร้างสภาพแวดล้อมใหม่สำหรับการเรียกใช้นั้น โดยมีสภาพแวดล้อมที่ครอบอยู่ของฟังก์ชันเป็นสภาพแวดล้อมแม่ ตัวแปรเฉพาะที่จากการเรียกใช้แต่ละครั้งจะไม่รบกวนกัน แม้เป็นการเรียกใช้แบบเวียนเกิด

factorial_r <- function(n) {
  # Each recursive call has its own local n
  if (n <= 1) return(1)
  n * factorial_r(n - 1)
}
cat('5! =', factorial_r(5), '\n')
cat('7! =', factorial_r(7), '\n')

rm() สำหรับลบตัวแปร

rm('name') หรือ rm(name) ลบการผูกชื่อออกจากสภาพแวดล้อมปัจจุบัน (หรือสภาพแวดล้อมที่ระบุ) ใช้สำหรับล้างตัวแปรชั่วคราว ส่ง envir = e เพื่อลบออกจากสภาพแวดล้อมที่กำหนด

x <- 42
y <- 'hello'
cat('Before rm:', ls(), '\n')
rm(x)
cat('After rm(x):', exists('x'), '\n')
rm('y')
cat('After rm(y):', exists('y'), '\n')

ตรวจสอบความเข้าใจอย่างรวดเร็ว

<<- ทำสิ่งใดที่ <- แบบปกติทำไม่ได้

ขอบเขต: ประเด็นสำคัญ

ประเด็นสำคัญเกี่ยวกับขอบเขตส่วนกลางกับขอบเขตเฉพาะที่:

  • <- ภายในฟังก์ชันสร้างตัวแปรเฉพาะที่ ตัวแปรส่วนกลางจะไม่เปลี่ยนแปลง
  • พารามิเตอร์ฟังก์ชันเป็นตัวแปรเฉพาะที่ R ส่งค่าด้วยค่า (มีการคัดลอกเมื่อแก้ไข)
  • <<- ไล่ขึ้นไปตามสายโซ่สภาพแวดล้อมแม่และแก้ไขการผูกชื่อแรกที่ตรงกัน
  • assign('x', val, envir=e) ใช้กำหนดค่าโดยระบุสภาพแวดล้อมเป้าหมายอย่างชัดเจน
  • local({...}) ให้ขอบเขตชั่วคราวโดยไม่ต้องสร้างฟังก์ชันที่มีชื่อ
  • หลีกเลี่ยงการบดบังชื่อสำคัญ (เช่น mean, c, T)
# Demonstrate local + <<- cleanly
running_sum <- 0
local({
  values <- c(10, 20, 30, 40)
  for (v in values) running_sum <<- running_sum + v
})
cat('Running sum:', running_sum, '\n')
cat('values in global:', exists('values'), '\n')

คำถามที่พบบ่อย

บทเรียน “ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่”

แยกความแตกต่างระหว่าง .GlobalEnv, environment ของฟังก์ชัน และคลอสเชอร์ คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม

ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. Environment ใน R คืออะไร
  2. กฎขอบเขตแบบเล็กซิคัล
  3. ขอบเขตส่วนกลางเทียบกับขอบเขตเฉพาะที่
  4. การสร้างและตรวจสอบ Environment
← กลับไปที่ R Academy