Hướng dẫn javascript are arrays passed by reference or value - javascript là các mảng được truyền bởi tham chiếu hoặc giá trị

Trong bài đăng này, chúng tôi sẽ xem xét vượt qua giá trị và vượt qua tham chiếu trong JavaScript.

Hãy cùng xem những gì được truyền qua giá trị và vượt qua tham chiếu trước khi xem xét bối cảnh JavaScript của nó.

Vượt qua giá trị:

Trong Pass by giá trị, hàm được gọi bằng cách truyền trực tiếp giá trị của biến làm đối số. Thay đổi đối số bên trong hàm không ảnh hưởng đến biến được truyền từ bên ngoài hàm.

JavaScript luôn vượt qua giá trị để thay đổi giá trị của biến không bao giờ thay đổi nguyên thủy cơ bản [chuỗi hoặc số]. so changing the value of the variable never changes the underlying primitive [String or number].

function callByValue[varOne, varTwo] { 
console.log["Inside Call by Value Method"];
varOne = 100;
varTwo = 200;
console.log["varOne =" + varOne +"varTwo =" +varTwo];
}
let varOne = 10;
let varTwo = 20;
console.log["Before Call by Value Method"];
console.log["varOne =" + varOne +"varTwo =" +varTwo];
callByValue[varOne, varTwo] console.log["After Call by Value Method"];
console.log["varOne =" + varOne +"varTwo =" +varTwo];

output will be :
---------------
Before Call by Value Method
varOne =10 varTwo =20
Inside Call by Value Method
varOne =100 varTwo =200
After Call by Value Method
varOne =10 varTwo =20

Tuy nhiên, khi một biến đề cập đến một đối tượng bao gồm mảng, giá trị là tham chiếu đến đối tượng.

Vượt qua tham chiếu:

Trong tham chiếu vượt qua, hàm được gọi bằng cách truyền trực tiếp tham chiếu/địa chỉ của biến làm đối số. Thay đổi đối số bên trong hàm ảnh hưởng đến biến được truyền từ bên ngoài hàm. Trong các đối tượng và mảng JavaScript theo sau vượt qua tham chiếu.

function callByReference[varObj] { 
console.log["Inside Call by Reference Method"];
varObj.a = 100;
console.log[varObj];
}
let varObj = {a:1};
console.log["Before Call by Reference Method"];
console.log[varObj];
callByReference[varObj] console.log["After Call by Reference Method"];
console.log[varObj];
output will be :
---------------
Before Call by Reference Method
{a: 1}
Inside Call by Reference Method
{a: 100}
After Call by Reference Method
{a: 100}

Vì vậy, nếu chúng ta chuyển đối tượng hoặc mảng làm đối số cho phương thức, thì có khả năng giá trị của đối tượng có thể thay đổi.

Nếu bạn muốn tạo trang web hoặc cổng thông tin - liên hệ với chúng tôi @ //www.bondesk.in

Ngôn ngữ lập trình đầu tiên tôi học được là C ++ và khi học nó, tôi đã học được về các giá trị và tham chiếu qua từng giá trị; C ++ sử dụng giá trị qua từng giá trị theo mặc định để chuyển các đối số vào các chức năng. Bạn có thể chỉ định rằng bạn muốn chuyển qua từng tham chiếu, tuy nhiên bằng cách đặt một ký tự ampers và giữa kiểu dữ liệu và tên tham số trong danh sách tham số trong định nghĩa chức năng. Tuy nhiên, JavaScript không cung cấp cho bạn các tùy chọn như vậy, nó có một quy tắc để mang lại tất cả và trong bóng tối ràng buộc chúng [đối số với các tham số, không phải là sinh vật của Trung Quốc với Chúa tể bóng tối]. Làm việc trên một ứng dụng ngày hôm nay, tôi đã gặp phải một vấn đề liên quan đến điều này mặc dù vậy, vì vậy, hãy để Lôi làm sáng tỏ bóng tối đó của những gì JavaScript làm đằng sau hậu trường khi chuyển các đối số vào một chức năng.

Kỉ niệm

Trước hết, hãy kiểm tra bộ nhớ nhanh và đưa ra sự khác biệt giữa các giá trị qua từng giá trị và chuyển qua. Các biến giữ dữ liệu trong bộ nhớ, nhưng một biến thực sự chỉ là một con trỏ đến một vị trí trong bộ nhớ. Bằng cách tạo một biến, bạn chỉ nói với chương trình của mình để chọn một khoảng trống trong bộ nhớ máy tính và nhớ nó để bạn có thể gán một giá trị cho nó và lấy giá trị đó khi bạn muốn.

Phần tham chiếu của các tham chiếu tham chiếu đề cập đến các vị trí bộ nhớ trong khi giá trị ‘trong các giá trị vượt qua đề cập đến giá trị thực tế ở vị trí bộ nhớ. Vì vậy, khi bạn sử dụng từng giá trị có nghĩa là bất kỳ đối số nào bạn chuyển đến một hàm chỉ có các giá trị của chúng được sao chép và chuyển sang các tham số bên trong định nghĩa hàm. Điều này có nghĩa là các tham số bên trong hàm không giống như các biến bạn đã truyền dưới dạng đối số. Chúng có cùng các giá trị, nhưng các giá trị đó được tạo ở các vị trí bộ nhớ mới, vì vậy nếu bạn thay đổi giá trị của một trong các tham số đó trong hàm thay đổi không ảnh hưởng đến biến bên ngoài hàm. Không có kết nối giữa đối số bên ngoài hàm và tham số bên trong hàm vì tất cả những gì bạn đã làm là vượt qua các giá trị, do đó qua giá trị.

// A pseudo-code example of pass-by-valuefunction funky[number] {
number = 7;
}
num = 5;
funky[num];
print num; // 5

Trong ví dụ trên, num biến vẫn bằng 5 mặc dù hàm FUNKY đã thay đổi nó thành 7 vì vị trí bộ nhớ mà Num trỏ đến Wasn được truyền vào hàm, chỉ có giá trị của nó, 5, đã được truyền. Vì vậy, Num không bị ảnh hưởng. Số tham số được tạo bởi hàm để trỏ đến một vị trí mới trong bộ nhớ chứa giá trị 5 và sau đó được thay đổi thành 7.

By-Ty-tham chiếu có nghĩa là bạn đang truyền không phải là giá trị của biến mà là vị trí bộ nhớ thực của biến. Bạn đang chuyển tham chiếu đến giá trị. Vì vậy, trong ví dụ tiếp theo này về tham chiếu qua từng lần, vị trí bộ nhớ cho NUM được chuyển vào hàm để số đó là một tham chiếu đến cùng một vị trí bộ nhớ. Rõ ràng điều này có nghĩa là bất cứ điều gì bạn làm với số cũng sẽ ảnh hưởng đến Num.

// A pseudo-code example of pass-by-referencefunction funky[number] {
number = 7;
}
num = 5;
funky[num];
print num; // 7

JavaScript từ Pass-By Rules

JavaScript tuân theo một quy tắc khi chuyển các đối số vào các chức năng, đó là có các quy tắc khác nhau!

JavaScript luôn sử dụng giá trị qua từng giá trị, tuy nhiên khi loại dữ liệu của đối số không phải là loại nguyên thủy thì giá trị được truyền thực sự là vị trí bộ nhớ. Vì vậy, năm loại nguyên thủy [chuỗi, số, booleans, null và không xác định] là có giá trị như bạn mong đợi. Nhưng bất kỳ loại loại dữ liệu phức tạp nào [đối tượng và mảng] đều có giá trị chuyển qua với tài liệu tham khảo của chúng là giá trị nên có hiệu lực, chúng được tham chiếu theo từng lần.

Ví dụ về cách JavaScript hành xử với các đối số nguyên thủy:

// primitive values are pass-by-valuefunction funky[number] {
number+= 7;
}
let num = 5;
funky[num];
console.log[num]; // 5

Ví dụ về cách JavaScript hành xử với các đối số không định hướng:

// non-primitive values are pass-by-referencefunction funky[arr, obj] {
arr.push[4];
obj.food = 'apple pie';
}
let myArr = [1,2,3];
let myObj = { name: 'Tony', food: 'pizza' };
funky[myArr, myObj];console.log[myArr]; // [1,2,3,4]
console.log[myObj]; // { name: 'Tony', food: 'apple pie' }

Trong ví dụ trên, bạn có thể thấy một đối tượng và một mảng được chuyển qua từng tham chiếu vì các biến bên ngoài Myarr và MYOBJ được thay đổi bên trong hàm. Điều này là do các vị trí bộ nhớ của Myarr và MYOBJ được chuyển vào hàm thay vì các giá trị mảng và đối tượng của chúng.

By-By-Reference là tốt vì điều đó có nghĩa là nếu bạn đang thao túng nhiều mảng hoặc đối tượng trong một chức năng mà bạn không cần phải trả lại nhiều thứ. Tuy nhiên, nếu bạn thực hành một cách lập trình chức năng hiệu ứng không bên thì điều này sẽ rất tệ vì chức năng của bạn, bằng cách thao tác các giá trị bên ngoài, đang thay đổi trạng thái bên ngoài của ứng dụng giá trị trả về của nó]. Dù sao, đó là một cuộc thảo luận cho một thời gian khác.

Thủ thuật của bộ nhớ

Tuy nhiên, điều này không có nghĩa là bạn có thể làm bất cứ điều gì bạn muốn đối tượng hoặc mảng và vẫn có những thay đổi của nó ảnh hưởng đến biến truyền ban đầu. Lý do là vị trí bộ nhớ. Nếu bạn thao tác các phần tử hoặc thuộc tính riêng lẻ của một mảng hoặc đối tượng thì tham chiếu đến biến đó không thay đổi, do đó, kết nối giữa đối số và tham số vẫn còn nguyên vì cả hai vẫn chỉ vào cùng một vị trí trong bộ nhớ.

Trong JavaScript bất cứ khi nào bạn gán một giá trị mới cho một biến, những gì xảy ra là một vị trí bộ nhớ mới được gán cho biến đó với giá trị đã cho tại vị trí đó trong bộ nhớ. Vì vậy, việc gán một mảng hoàn toàn mới cho một tham số mảng trong một hàm làm cho tham số đó trỏ đến một vị trí bộ nhớ mới, trong khi biến mảng gốc bên ngoài hàm vẫn trỏ đến vị trí bộ nhớ gốc. Điều tương tự nếu bạn gán một đối tượng mới theo nghĩa đen cho một tham số đối tượng trong một hàm. Điều này có nghĩa là liên kết [vị trí bộ nhớ chia sẻ] giữa đối số bên ngoài và tham số bên trong bị phá vỡ để các thay đổi bên trong hàm sẽ không ảnh hưởng đến các đối số bên ngoài hàm.

Ví dụ mã cuối cùng giữ nguyên các tham chiếu vì hàm trực tiếp thao tác với mảng và đối tượng bằng cách sử dụng phương thức đẩy mảng mảng để thêm phần tử và thay đổi trực tiếp một giá trị trên một thuộc tính của đối tượng. Chức năng đã tạo ra một mảng hoặc đối tượng mới, nó chỉ thay đổi các phần của chúng - nó đã thay đổi các giá trị phần tử/thuộc tính của chúng, không phải các tài liệu tham khảo mảng/đối tượng.

Tuy nhiên, trong ví dụ dưới đây, tôi sẽ chỉ ra cách bạn có thể phá vỡ liên kết tham chiếu giữa đối số bên ngoài và tham số bên trong bằng cách gán một giá trị hoàn toàn mới cho tham số.

// example changing memory locations, thereby breaking reference linkfunction funky[arr, obj] {
arr = [-1,-2,-3];
obj = { age: 12 };
console.log[arr]; // [-1,-2,-3]
console.log[obj]; // { age: 12 }
}
let myArr = [1,2,3];
let myObj = { name: 'Tony', food: 'pizza' };
funky[myArr, myObj];console.log[myArr]; // [1,2,3]
console.log[myObj]; // { name: 'Tony', food: 'pizza' }

Trong ví dụ trên khi [-1, -2, -3] được gán cho tham số mảng, điều xảy ra là JavaScript tạo một vị trí bộ nhớ mới cho [-1, -2, -3] và gán vị trí bộ nhớ đó cho ARR. Các vị trí bộ nhớ cho ARR và Myarr bây giờ khác nhau nên ARR không còn ảnh hưởng đến Myarr. Điều tương tự đã xảy ra giữa Obj và Myobj.

Vấn đề của tôi

Lý do tôi đã viết bài viết này là vì tôi gặp phải một vấn đề hôm nay trong ứng dụng mà tôi đang làm việc ở nơi tôi mong đợi mảng tôi đã chuyển vào một chức năng sẽ được thay đổi dựa trên những gì tôi đã làm trong chức năng nhưng tôi nhận ra thật đáng buồn là nó không 't. Hãy để xem những gì tôi đang làm.

Tôi đã có một mảng ID người dùng và một mảng song song các tọa độ GPS của họ. Tôi muốn chuyển cả hai mảng vào hàm, cùng với khoảng cách tối đa và thêm một cặp tọa độ GPS, sau đó tìm ra khoảng cách giữa mỗi cặp tọa độ trong mảng và cặp tọa độ độc lập. Hàm sẽ lọc ra người dùng từ mảng người dùng ở xa hơn khoảng cách tối đa và tạo một mảng khoảng cách để phù hợp với người dùng còn lại trong mảng. Mảng khoảng cách mới này được trả về từ hàm và được gán cho một mảng bên ngoài hàm để biểu thị khoảng cách mà mỗi người dùng là từ cặp tọa độ độc lập.

Về cơ bản, tôi muốn lọc người dùng bằng khoảng cách tối đa và trả về một cặp khoảng cách phù hợp cho mỗi người dùng.

Điều quan trọng đối với chức năng này là thực tế là các mảng được truyền qua tham chiếu để mảng người dùng bên ngoài sẽ được lọc xuống bên trong hàm. Ngoại trừ tôi đã sử dụng phương thức bộ lọc mảng JavaScript, Array.prototype.filter, trả về một mảng hoàn toàn mới có tham chiếu đến vị trí bộ nhớ mới được phân bổ. Vì vậy, bên trong hàm khi tôi gán kết quả của bộ lọc cho tham số mảng người dùng được gán một vị trí bộ nhớ mới cho mảng, do đó mảng người dùng bên ngoài hàm và mảng người dùng bên trong hàm không còn trỏ đến cùng một vị trí bộ nhớ. Điều này có nghĩa là tôi đã thực sự nhận được mảng được lọc ra khỏi chức năng.

Dưới đây là một số mã cơ bản cho thấy vấn đề:

userArray;       // filled with user IDs
coordsArray; // filled with coordinates for each user from userArray
myCoords; // has pair of coordinates for this user in lat, lon properties
maxDist; // holds a number
let distArray = convertGpsToMiles[userArray, coordsArray, myCoords, maxDist];console.log[userArray]; // still holds original userArray unfilteredfunction convertGpsToMiles[users, coords, myLocation, maxD] {
let miles;
let distances = [];
users = users.filter[[el, index] => {
miles = convertCoordsToDistance[myLocation, coords[i].lat, coords[i].lon];
if [miles

Bài Viết Liên Quan

Chủ Đề