Truyền mảng javascript theo tham chiếu

Les biến sont passées par valeur, les objets par référence. Tableaux trong JavaScript sont des objets

Chúng tôi sẽ kiểm tra từng trường hợp

Trường hợp của một biến đơn giản

Hàm test[] thêm một chuỗi vào một chuỗi được cung cấp dưới dạng tham số

function test[z]
{
   z = z + "suffix";
}

var x = "demo";
test[x];
document.write[x];

Người ta có thể xác minh rằng biến x không bị sửa đổi bên ngoài ngữ cảnh của hàm

Điều tương tự cũng đúng với một số

Trường hợp của một đối tượng Chuỗi

var x = new String["demo"];
test[x];
document.write[x];

Các đối tượng đơn giản như Chuỗi, Boolean, Số, được truyền theo giá trị

Trường hợp của một đối tượng Array

Hàm testa[] thêm một phần tử vào một mảng được cung cấp dưới dạng tham số

function testa[a]
{
   a.push["lastitem"];
}

x = new Array["one", "two", "three"];
testa[x];
document.write[x];

Chúng ta thấy rằng một Mảng được truyền theo tham chiếu, vì phần tử "lastitem" được thêm vào phần thân hàm được bao gồm trong mảng sau lệnh gọi hàm

Điều này có đúng với một mảng được khai báo là một chữ không?

var y = [1, 2, 3];
testa[y];
document.write[y];

câu trả lời là có

Tóm lại, nếu chúng ta muốn truyền một biến đơn giản theo tham chiếu, nó phải được đưa vào một mảng. Code sẽ được sửa đổi như sau

x = "demo";
x = [x];
testa[x];
x = x.join[''];
document.write[x];

Hàm join[] chuyển đổi mảng thành chuỗi sau khi gọi hàm. Điều này làm tăng mã nhưng do thiếu toán tử hủy hội nghị trong JavaScript, đây vẫn là cách dễ nhất để chuyển một chuỗi theo tham chiếu

Hoàn thành ví dụ để chuyển một chuỗi theo tham chiếu

function testb[a]
{
  var x = a[0];	
  x += "suffix";
  a[0] = x;
} 

x = "demo";
x = [x];
testb[x];
x = x[0];
document.write[x];

Chuỗi, mặc dù được sửa đổi trong hàm, nhưng một phần của mảng bị thay đổi trong phạm vi toàn cầu. Nó phức tạp hơn, nhưng có thể

Phép gán bên trong hàm

Việc gán trong một hàm, cho một đối tượng hoặc một mảng không có tác dụng bên ngoài phạm vi của hàm. Đây là lý do tại sao việc đưa ra một đối tượng làm đối số đôi khi được gọi là "chia sẻ cuộc gọi" thay vì "gọi theo tham chiếu"

var ta = [ "a", "b", "c"]
function testb[x] {
   x = ["zero"]
}
testb[ta]
document.write[ta]

Kết quả

Vì vậy, nếu chúng ta muốn khởi tạo một mảng hoặc đối tượng trong một hàm, chúng ta phải xóa nội dung của nó thay vì gán nó bằng [] hoặc {}

Trong JavaScript, khi một hàm được gọi, các đối số có thể được truyền theo hai cách, Truyền theo giá trị hoặc Truyền theo tham chiếu [địa chỉ]. Các loại dữ liệu nguyên thủy như chuỗi, số, null, không xác định và boolean, được truyền theo giá trị trong khi các loại dữ liệu không nguyên thủy như đối tượng, mảng và hàm được truyền theo tham chiếu trong Javascript

Phạm vi của Điều khoản

  • Bài viết này định nghĩa truyền theo giá trị và truyền theo phương thức tham chiếu trong javascript. Chúng ta cũng sẽ tìm hiểu sự khác biệt giữa hai phương pháp này và khi nào thì sử dụng phương pháp nào
  • Ghi chú. Bài viết này không giải thích pass-by-value và pass-by-reference đối với các ngôn ngữ lập trình khác

Các kiểu dữ liệu nguyên thủy và không nguyên thủy

Trước khi hiểu về pass-by-value và pass-by-reference trong JavaScript, trước tiên, hãy hiểu kiểu dữ liệu nguyên thủy và không nguyên thủy là gì. Vì vậy, trong JavaScript, các loại dữ liệu được chia thành hai loại lớn

Các kiểu dữ liệu như chuỗi, số, null, không xác định, ký hiệu và boolean thuộc danh mục kiểu dữ liệu Nguyên thủy, trong khi tất cả các đối tượng, mảng và hàm thuộc danh mục kiểu dữ liệu không nguyên thủy hoặc tham chiếu

Sự khác biệt chính giữa nguyên thủy và không nguyên thủy là nguyên thủy là bất biến. e. không có cách nào để thay đổi giá trị nguyên thủy sau khi nó được tạo, trong khi giá trị không nguyên thủy có thể thay đổi được. e. giá trị của một đối tượng có thể được thay đổi sau khi nó được tạo ra

Kiểu dữ liệu nguyên thủy

var string = 'Scaler Acadmey';
string[7] = 'a'
console.log[string] // 'Scaler Acadmey'

Ghi chú

________số 8

Trong ví dụ nêu trên, đầu tiên, chúng tôi đã chỉ định Scaler cho 'myString', sau đó chúng tôi ghi nhật ký vào bảng điều khiển và chúng tôi có Scaler trong bảng điều khiển, sau đó chúng tôi gắn giá trị " Academy" vào giá trị hiện tại của 'myString' và trên bảng điều khiển ghi nhật ký giá trị đó . Bây giờ bạn có thể hỏi làm thế nào nó có thể xảy ra như tôi đã đề cập rằng các kiểu dữ liệu nguyên thủy là bất biến và chuỗi là một trong số đó?

Để hiểu điều này, chúng ta cần chia quá trình thành các bước

  1. Đầu tiên, giá trị hiện tại của "myString" được tìm nạp, tôi. e. , "Máy chia tỷ lệ"
  2. "Học viện" được thêm vào giá trị hiện có
  3. Sau đó, giá trị kết quả, tôi. e. "Scaler Academy" được phân bổ cho một khối bộ nhớ mới
  4. Bây giờ, đối tượng"myString" trỏ đến không gian bộ nhớ mới được tạo [không gian mà giá trị kết quả được phân bổ trong bước thứ ba]
  5. Bây giờ, không gian bộ nhớ được tạo trước đó [i. e. , không gian của myString = "String"] có sẵn để thu gom rác

Do đó, chúng tôi đi đến kết luận rằng giá trị được tạo trước đó không bị sửa đổi, nó được gửi để thu gom rác trong khi biến 'myString' hiện trỏ đến không gian bộ nhớ mới được tạo, có "Scaler Academy" được lưu trữ trong đó. Nói một cách đơn giản, chúng ta chỉ tạo biến trỏ đến một không gian khác trong bộ nhớ và không sửa đổi giá trị hiện tại của nó

Các kiểu dữ liệu nguyên thủy được so sánh theo giá trị. Nếu hai giá trị giống nhau, thì chúng hoàn toàn bằng nhau

var num1 = 40;
var num2 = 40;
numb1 === num2; // true

var string1 = 'Scaler Academy';
var string2 = 'Scaler Academy';
string1 === string2; // true

Các kiểu dữ liệu không nguyên thủy

var x = new String["demo"];
test[x];
document.write[x];
0

Các đối tượng và mảng không được so sánh theo giá trị. Điều đó có nghĩa là ngay cả khi hai đối tượng và mảng có cùng giá trị và thuộc tính hoặc cùng các phần tử tương ứng, chúng không hoàn toàn bằng nhau

var x = new String["demo"];
test[x];
document.write[x];
1

Hai đối tượng hoàn toàn bằng nhau chỉ khi chúng đề cập đến cùng một đối tượng

var x = new String["demo"];
test[x];
document.write[x];
2

Giá trị không nguyên thủy đôi khi còn được gọi là loại tham chiếu vì thay vì giá trị, chúng được so sánh bằng tham chiếu

Ghi chú. Trong JavaScript, các giá trị nguyên thủy được lưu trữ trên ngăn xếp, trong khi các giá trị không nguyên thủy được lưu trữ trong một đống

Truyền theo giá trị trong JavaScript

Truyền giá trị trong JavaScript có nghĩa là một bản sao giá trị của tham số thực tế được tạo trong bộ nhớ i. e. , cấp phát bộ nhớ mới được thực hiện và tất cả các thay đổi được thực hiện trong giá trị mới đó [i. e. , giá trị được sao chép]. Giá trị ban đầu và giá trị được sao chép độc lập với nhau vì cả hai đều có một không gian khác nhau trong bộ nhớ i. e. , khi thay đổi giá trị bên trong hàm thì biến bên ngoài hàm không bị ảnh hưởng

Nói một cách đơn giản, chúng ta có thể hiểu là, trong một giá trị truyền vào, hàm nhận một bản sao của biến, bản sao này độc lập với biến ban đầu được truyền vào

Truyền giá trị trong JavaScript yêu cầu nhiều không gian hơn vì các hàm nhận được một bản sao của nội dung thực, do đó, một biến mới được tạo trong bộ nhớ

Trong khái niệm này, toán tử bằng đóng một vai trò lớn. Khi chúng ta tạo một biến, toán tử bằng sẽ thông báo xem bạn đang gán cho biến đó một giá trị nguyên thủy hay không nguyên thủy và sau đó hoạt động tương ứng

Ghi chú. Khi chúng ta sử dụng toán tử =, sẽ có một lệnh gọi hàm [đằng sau] trong đó việc chuyển giá trị [hoặc tham chiếu] trong JavaScript được thực hiện

Khi chúng ta gán cho một biến một giá trị nguyên thủy, toán tử bằng sẽ thiết lập một khoảng trống [vị trí/địa chỉ] trong bộ nhớ [giả sử tại địa chỉ 2001] để lưu trữ dữ liệu của biến đó [num1] vào địa chỉ đó

Bây giờ, khi chúng ta tạo một biến mới num2 [ví dụ như ở địa chỉ 2002] và gán cho nó giá trị của biến trước đó num1, toán tử bằng sẽ tạo KHÔNG GIAN MỚI trong bộ nhớ độc lập với biến trước đó num1 có địa chỉ 2001 và đặt bản sao của nó . Do đó, điều này sao chép giá trị của biến ban đầu, num1, vào hai vị trí riêng biệt trong bộ nhớ [với địa chỉ 2001 và 2002]

var x = new String["demo"];
test[x];
document.write[x];
3

Ở đây, chúng tôi đã gán cho num1 một giá trị là 70. Điều này tạo ra một không gian trong bộ nhớ theo tên num1 và địa chỉ 2001 [giả định]. Khi chúng ta tạo một biến num2 và gán cho nó giá trị của num1, thì toán tử equals thông báo rằng chúng ta đang xử lý một giá trị nguyên thủy, do đó nó tạo một KHÔNG GIAN MỚI trong bộ nhớ có địa chỉ 2002 và gán cho nó một bản sao của giá trị của num1, i. e. 70. Bây giờ chúng ta có thể thấy rằng cả hai biến đều có các khoảng trống khác nhau trong bộ nhớ và cả hai đều có giá trị là 70

Bây giờ, nếu chúng ta thay đổi giá trị của num1, thì num2 sẽ không có tác dụng vì nó có không gian riêng trong bộ nhớ và bây giờ nó không liên quan gì đến giá trị của num2 vì cả hai đều có không gian [địa chỉ] khác nhau trong bộ nhớ

Hãy hiểu điều này tốt hơn bằng một ví dụ khác

var x = new String["demo"];
test[x];
document.write[x];
4

Từ đoạn mã trên, chúng ta có thể thấy rằng hàm nhân nhận một đối số và thay đổi giá trị của nó

Sau đó, chúng tôi đã khai báo một biến num, với giá trị là 30

Sau đó, chúng ta chuyển biến num cho hàm nhân. Javascript tự động sao chép giá trị của biến num sang biến tmp. Vì vậy, ở đây tmp là một biến mới được phân bổ một không gian mới trong bộ nhớ và độc lập với num

Bây giờ tất cả các thay đổi do phép nhân hàm thực hiện được thực hiện trực tiếp với biến tmp;

Điều này xảy ra vì một bản sao riêng biệt của biến num được tạo trong bộ nhớ có tên tmp với giá trị ban đầu là 30, giá trị này sau khi tính toán sẽ trở thành 1500

tmp và num không có liên kết với nhau tôi. e. , chúng độc lập với nhau

Chuyển qua tham chiếu trong JavaScript

Không giống như truyền theo giá trị trong JavaScript, truyền theo tham chiếu trong JavaScript không tạo khoảng trống mới trong bộ nhớ, thay vào đó, chúng ta truyền tham chiếu/địa chỉ của tham số thực, nghĩa là hàm có thể truy cập giá trị ban đầu của biến. Như vậy, nếu chúng ta thay đổi giá trị của biến bên trong hàm thì giá trị ban đầu cũng bị thay đổi theo.

Nó không tạo bản sao, thay vào đó, nó hoạt động trên biến ban đầu, vì vậy tất cả các thay đổi được thực hiện bên trong hàm cũng ảnh hưởng đến biến ban đầu

Không giống như giá trị truyền qua trong JavaScript, ở đây, khi toán tử bằng xác định rằng biến obj1 được đặt bằng một đối tượng, nó sẽ tạo một không gian bộ nhớ mới và trỏ obj1 đến 3005[giả định địa chỉ]. Bây giờ, khi chúng ta tạo một biến mới, obj2 và gán nó với giá trị của obj1, toán tử bằng xác định rằng chúng ta đang xử lý các kiểu dữ liệu không nguyên thủy; . Do đó, chúng ta có thể thấy rằng không có không gian bộ nhớ mới nào được tạo ra thay vào đó, cả hai biến đều trỏ đến cùng một địa chỉ mà obj1 đã trỏ đến

var x = new String["demo"];
test[x];
document.write[x];
5

Trong ví dụ trên, chúng ta đã tạo một biến obj1 và đặt nó bằng một đối tượng, sau đó chúng ta đặt giá trị của biến obj2 khác bằng obj1

Vì toán tử bằng xác định rằng chúng ta đang xử lý các kiểu dữ liệu không nguyên thủy, nên thay vì tạo một không gian bộ nhớ mới, nó trỏ obj2 đến cùng một không gian bộ nhớ mà obj1 được trỏ đến. Do đó, khi chúng ta thay đổi [biến đổi] giá trị của obj1, thì giá trị của obj2 cũng bị thay đổi do obj2 cũng trỏ đến cùng một không gian bộ nhớ như obj1.

Chuyển qua Tham chiếu trong Đối tượng [có Chức năng]

var x = new String["demo"];
test[x];
document.write[x];
6

Từ ví dụ trên, chúng ta có thể thấy rằng khi thay đổi giá trị tmpObj thì giá trị của originalObj cũng bị thay đổi. Lý do cho điều này là khi chúng ta gọi demo và truyền đối tượng, thì originalObj được truyền theo tham chiếu của nó, vì vậy tham số cục bộ tempObj sẽ trỏ đến cùng một đối tượng mà chúng ta đã xác định, i. e. , Obj ban đầu

Vì vậy, trong trường hợp này, chúng tôi không xử lý hai bản sao độc lập thay vào đó, chúng tôi có các biến trỏ đến cùng một đối tượng, vì vậy, bất kỳ thay đổi nào được thực hiện đối với đối tượng này sẽ hiển thị với biến kia

Truyền tham chiếu trong một mảng [có chức năng]

let myString = "Scaler";
console.log[myString]; // Scaler

myString = myString + " Academy";
console.log[myString]; // Scaler Academy
0

Ở đây, khi chúng ta cố gắng thêm một mục mới vào mảng được lưu trữ trong tempArr, nó cũng ảnh hưởng đến mảng originalArr. Điều này xảy ra vì không có hai bản sao riêng biệt của một mảng, chúng tôi chỉ xử lý một mảng. Biến tempArr tham chiếu đến cùng một mảng đã được khởi tạo trong biến originalArr

Ví dụ này nói rằng, giống như đối tượng, trong mảng cũng vậy, khi thay đổi giá trị của tempArr, giá trị của originalArr sẽ tự động thay đổi

Do đó, chúng ta có thể kết luận bằng cách nói rằng tất cả các loại dữ liệu không nguyên thủy đều tương tác với nhau theo tham chiếu, vì vậy khi chúng ta đặt các giá trị của chúng bằng nhau hoặc chuyển chúng cho một hàm, thì tất cả chúng đều trỏ đến cùng một không gian bộ nhớ [địa chỉ] bất cứ khi nào chúng ta thay đổi

Khi nào nên sử dụng Pass by Value?

Như trong giá trị truyền qua trong JavaScript, một bản sao mới của biến được tạo và mọi thay đổi được thực hiện trong biến mới đều độc lập với biến ban đầu, vì vậy sẽ hữu ích khi chúng ta muốn theo dõi biến ban đầu và không'

Khi nào nên sử dụng Pass by Reference?

Khi chúng ta chuyển các đối số có kích thước lớn, tốt hơn là sử dụng tham chiếu chuyển tiếp trong JavaScript vì không có bản sao riêng biệt nào được tạo trong hàm được gọi, vì vậy bộ nhớ không bị lãng phí và do đó chương trình hiệu quả hơn

Mảng JavaScript có được chuyển qua tham chiếu không?

Trong Javascript các đối tượng và mảng được truyền theo tham chiếu .

JavaScript được truyền theo giá trị hay truyền theo tham chiếu?

Nó luôn truyền theo giá trị, nhưng đối với các đối tượng, giá trị của biến là một tham chiếu . Do đó, khi bạn truyền một đối tượng và thay đổi các thành viên của nó, những thay đổi đó vẫn tồn tại bên ngoài hàm. Điều này làm cho nó trông giống như vượt qua tham chiếu.

JavaScript có luôn truyền tham số theo giá trị hoặc theo tham chiếu không?

Javascript luôn truyền theo giá trị, nhưng khi một biến đề cập đến một đối tượng [bao gồm cả mảng], "giá trị" là một tham chiếu đến đối tượng. Việc thay đổi giá trị của một biến không bao giờ thay đổi nguyên hàm hoặc đối tượng cơ bản, nó chỉ trỏ biến đó tới một nguyên hàm hoặc đối tượng mới

Các chuỗi JavaScript có được chuyển qua tham chiếu không?

Trên thực tế, Chuỗi trong Javascript thực sự được truyền “theo tham chiếu” . Do đó, việc gọi một hàm bằng một chuỗi không liên quan đến việc sao chép nội dung của chuỗi. Tuy nhiên, Chuỗi JavaScript là bất biến; .

Chủ Đề