Giới thiệu lập trình viên chức năng Giới thiệu về JavaScript (Phần mềm soạn thảo)

Khối khói nghệ thuật để hút thuốc - MattysFlicks - (CC BY 2.0)
Lưu ý: Đây là một phần của sê-ri Phần mềm soạn thảo phần mềm (bây giờ là một cuốn sách!) Về việc học lập trình chức năng và các kỹ thuật phần mềm tổng hợp trong JavaScriptES6 + từ đầu. Hãy theo dõi. Có rất nhiều điều này sẽ đến!
Mua sách | Chỉ số |

Đối với những người không quen thuộc với JavaScript hoặc ES6 +, đây là mục đích giới thiệu ngắn gọn. Cho dù bạn là người mới bắt đầu hay nhà phát triển JavaScript có kinh nghiệm, bạn có thể học được điều gì đó mới. Những điều sau đây chỉ có nghĩa là làm trầy xước bề mặt và khiến bạn phấn khích. Nếu bạn muốn biết nhiều hơn, bạn sẽ phải khám phá sâu hơn. Có rất nhiều phía trước.

Cách tốt nhất để học viết mã là viết mã. Tôi khuyên bạn nên theo dõi bằng cách sử dụng môi trường lập trình JavaScript tương tác như CodePen hoặc Babel REPL.

Ngoài ra, bạn có thể thoát khỏi bằng cách sử dụng REPL của Node hoặc bảng điều khiển trình duyệt.

Biểu thức và giá trị

Một biểu thức là một đoạn mã đánh giá một giá trị.

Sau đây là tất cả các biểu thức hợp lệ trong JavaScript:

7;
7 + 1; // số 8
7 * 2; // 14
'Xin chào'; // Xin chào

Giá trị của một biểu thức có thể được đặt tên. Khi bạn làm như vậy, biểu thức được ước tính trước và giá trị kết quả được gán cho tên. Đối với điều này, chúng tôi sẽ sử dụng từ khóa const. Đây không phải là cách duy nhất, nhưng đó là cách bạn sẽ sử dụng nhiều nhất, vì vậy chúng tôi sẽ gắn bó với const bây giờ:

const xin chào = 'Xin chào';
xin chào; // Xin chào

var, let và const

JavaScript hỗ trợ thêm hai từ khóa khai báo biến: var và let. Tôi thích nghĩ về họ theo thứ tự lựa chọn. Theo mặc định, tôi chọn khai báo nghiêm ngặt nhất: const. Một biến được khai báo với từ khóa const không thể được chỉ định lại. Giá trị cuối cùng phải được chỉ định tại thời điểm khai báo. Điều này nghe có vẻ cứng nhắc, nhưng hạn chế là một điều tốt. Đó là một tín hiệu cho bạn biết, "giá trị được gán cho tên này sẽ không thay đổi". Nó giúp bạn hiểu đầy đủ ý nghĩa của cái tên ngay lập tức mà không cần phải đọc toàn bộ chức năng hoặc phạm vi khối.

Đôi khi, nó rất hữu ích để gán lại các biến. Ví dụ: nếu bạn sử dụng thủ công, lặp lại bắt buộc thay vì một cách tiếp cận chức năng hơn, bạn có thể lặp lại một bộ đếm được gán với let.

Bởi vì var cho bạn biết ít nhất về biến, đó là tín hiệu yếu nhất. Kể từ khi tôi bắt đầu sử dụng ES6, tôi chưa bao giờ cố ý khai báo var trong một dự án phần mềm thực sự.

Xin lưu ý rằng một khi một biến được khai báo bằng let hoặc const, mọi nỗ lực khai báo lại sẽ dẫn đến lỗi. Nếu bạn thích linh hoạt thử nghiệm hơn trong môi trường REPL (Đọc, Eval, Vòng lặp in), bạn có thể sử dụng var thay vì const để khai báo biến. Vareclaring var được cho phép.

Văn bản này sẽ sử dụng const để giúp bạn có thói quen mặc định const cho các chương trình thực tế, nhưng hãy thoải mái thay thế var cho mục đích thử nghiệm tương tác.

Các loại

Cho đến nay, chúng tôi đã thấy hai loại: số và chuỗi. JavaScript cũng có booleans (đúng hoặc sai), mảng, đối tượng và hơn thế nữa. Chúng ta sẽ đến các loại khác sau.

Một mảng là một danh sách sắp xếp các giá trị. Hãy nghĩ về nó như một hộp có thể chứa nhiều vật phẩm. Đây là ký hiệu mảng theo nghĩa đen:

[1, 2, 3];

Tất nhiên, đó là một biểu thức có thể được đặt tên:

const mảng = [1, 2, 3];

Một đối tượng trong JavaScript là một tập hợp các cặp khóa: value. Nó cũng có một ký hiệu theo nghĩa đen:

{
  giá trị cốt lõi'
}

Và tất nhiên, bạn có thể gán một đối tượng cho một tên:

const foo = {
  thanh: 'thanh'
}

Nếu bạn muốn gán các biến hiện có cho các khóa thuộc tính đối tượng cùng tên, thì có một phím tắt cho điều đó. Bạn chỉ có thể nhập tên biến thay vì cung cấp cả khóa và giá trị:

const a = 'a';
const oldA = {a: a}; // cách dài, dư thừa
const oA = {a}; // ngắn một ngọt ngào!

Để giải trí, hãy để Lừa làm điều đó một lần nữa:

const b = 'b';
const oB = {b};

Các đối tượng có thể dễ dàng được kết hợp với nhau thành các đối tượng mới:

const c = {... oA, ... oB}; // {a: 'a', b: 'b'}

Những chấm đó là toán tử trải rộng đối tượng. Nó lặp lại các thuộc tính trong oA và gán chúng cho đối tượng mới, sau đó thực hiện tương tự cho oB, ghi đè bất kỳ khóa nào đã tồn tại trên đối tượng mới. Theo văn bản này, đối tượng trải rộng là một tính năng thử nghiệm mới, có thể chưa có trong tất cả các trình duyệt phổ biến, nhưng nếu nó không hoạt động cho bạn, có một thay thế: Object.assign ():

const d = Object.assign ({}, oA, oB); // {a: 'a', b: 'b'}

Chỉ gõ thêm một chút trong ví dụ Object.assign () và nếu bạn đang soạn nhiều đối tượng, nó thậm chí có thể giúp bạn tiết kiệm một số thao tác gõ. Lưu ý rằng khi bạn sử dụng Object.assign (), bạn phải truyền đối tượng đích làm tham số đầu tiên. Nó là đối tượng mà các thuộc tính sẽ được sao chép vào. Nếu bạn quên và bỏ qua đối tượng đích, đối tượng bạn vượt qua trong đối số đầu tiên sẽ bị thay đổi.

Theo kinh nghiệm của tôi, việc thay đổi một đối tượng hiện có thay vì tạo ra một đối tượng mới thường là một lỗi. Ít nhất, nó dễ bị lỗi. Hãy cẩn thận với Object.assign ().

Phá hủy

Cả hai đối tượng và mảng đều hỗ trợ hủy, nghĩa là bạn có thể trích xuất các giá trị từ chúng và gán chúng cho các biến được đặt tên:

const [t, u] = ['a', 'b'];
t; // 'a'
u; // 'b'
const blep = {
  blop: 'blop'
};

// Sau đây là tương đương với:
// const blop = blep.blop;
const {blop} = blep;
blop; // 'blop'

Như với ví dụ mảng ở trên, bạn có thể cấu trúc thành nhiều bài tập cùng một lúc. Ở đây, một dòng bạn sẽ thấy trong nhiều dự án Redux:

const {loại, tải trọng} = hành động;

Ở đây, cách thức mà nó được sử dụng trong bối cảnh của bộ giảm tốc (nhiều hơn về chủ đề đó đến sau):

const myReducer = (state = {}, hành động = {}) => {
  const {loại, tải trọng} = hành động;
  công tắc (loại) {
    trường hợp 'FOO': return Object.assign ({}, trạng thái, tải trọng);
    mặc định: trạng thái trả về;
  }
};

Nếu bạn không muốn sử dụng tên khác cho ràng buộc mới, bạn có thể gán tên mới:

const {blop: bloop} = blep;
bloop; // 'blop'

Đọc: Gán blep.blop là bloop.

So sánh và Ternaries

Bạn có thể so sánh các giá trị với toán tử đẳng thức nghiêm ngặt (đôi khi được gọi là ba bộ ba tương đương với nhau):

3 + 1 === 4; // thật

Có một nhà điều hành bình đẳng cẩu thả. Nó chính thức được biết đến như là nhà điều hành của Equal Viking. Một cách không chính thức, đôi khi bằng nhau. Double Equals có một hoặc hai trường hợp sử dụng hợp lệ, nhưng thay vào đó, hầu như luôn luôn tốt hơn để mặc định cho toán tử ===.

Các toán tử so sánh khác bao gồm:

  • > Lớn hơn
  • <Ít hơn
  • > = Lớn hơn hoặc bằng
  • <= Nhỏ hơn hoặc bằng
  • ! = Không bằng
  • ! == Không nghiêm ngặt bằng
  • && Hợp lý và
  • | | Hợp lý hay

Biểu thức ternary là một biểu thức cho phép bạn đặt câu hỏi bằng cách sử dụng một bộ so sánh và đánh giá một câu trả lời khác nhau tùy thuộc vào việc biểu thức đó có đúng hay không:

14 - 7 === 7? 'Vâng!' : 'Không.'; // Vâng!

Chức năng

JavaScript có các biểu thức hàm, có thể được gán cho tên:

const đôi = x => x * 2;

Điều này có nghĩa tương tự như hàm toán học f (x) = 2x. Nói to, hàm đó đọc f của x bằng 2x. Hàm này chỉ thú vị khi bạn áp dụng nó cho một giá trị cụ thể của x. Để sử dụng hàm trong các phương trình khác, bạn sẽ viết f (2), có cùng ý nghĩa với 4.

Nói cách khác, f (2) = 4. Bạn có thể nghĩ về một hàm toán học như một ánh xạ từ đầu vào đến đầu ra. f (x) trong trường hợp này là ánh xạ các giá trị đầu vào cho x thành các giá trị đầu ra tương ứng bằng với sản phẩm của giá trị đầu vào và 2.

Trong JavaScript, giá trị của biểu thức hàm là chính hàm:

gấp đôi; // [Hàm: nhân đôi]

Bạn có thể xem định nghĩa hàm bằng phương thức .toString ():

double.toString (); // 'x => x * 2'

Nếu bạn muốn áp dụng một hàm cho một số đối số, bạn phải gọi nó bằng một lệnh gọi hàm. Một lời gọi hàm áp dụng một hàm cho các đối số của nó và đánh giá một giá trị trả về.

Bạn có thể gọi một hàm bằng cách sử dụng (argument1, argument2, ... rest). Ví dụ: để gọi hàm kép của chúng ta, chỉ cần thêm dấu ngoặc đơn và chuyển vào một giá trị để nhân đôi:

gấp đôi (2); // 4

Không giống như một số ngôn ngữ chức năng, những dấu ngoặc đơn có ý nghĩa. Không có chúng, hàm won đã được gọi là:

đôi 4; // Cú phápError: Số bất ngờ

Chữ ký

Các chức năng có chữ ký, bao gồm:

  1. Một tên chức năng tùy chọn.
  2. Một danh sách các loại tham số, trong ngoặc đơn. Các tham số có thể tùy chọn được đặt tên.
  3. Loại giá trị trả về.

Kiểu chữ ký don lồng cần được chỉ định trong JavaScript. Công cụ JavaScript sẽ tìm ra các loại trong thời gian chạy. Nếu bạn cung cấp đủ manh mối, chữ ký cũng có thể được suy ra bởi các công cụ dành cho nhà phát triển như IDE (Môi trường phát triển tích hợp) và Tern.js bằng cách sử dụng phân tích luồng dữ liệu.

JavaScript thiếu ký hiệu chữ ký hàm riêng, do đó, có một vài tiêu chuẩn cạnh tranh: JSDoc đã rất phổ biến trong lịch sử, nhưng nó dài dòng một cách khó xử và không ai bận tâm để giữ các nhận xét tài liệu cập nhật với mã, vì vậy nhiều nhà phát triển JS đã ngừng sử dụng nó

TypeScript và Flow hiện đang là ứng cử viên lớn. Tôi không chắc chắn làm thế nào để diễn đạt mọi thứ tôi cần trong một trong hai thứ đó, vì vậy tôi chỉ sử dụng Rtype, cho mục đích tài liệu. Một số người rơi vào các loại cà ri chỉ dành cho cà ri của Haskell. Tôi rất thích thấy một hệ thống ký hiệu tốt được chuẩn hóa cho JavaScript, nếu chỉ cho mục đích tài liệu, nhưng tôi không nghĩ rằng bất kỳ giải pháp hiện tại nào đều phù hợp với nhiệm vụ hiện tại. Ngay bây giờ, hãy nheo mắt và cố hết sức để theo kịp các chữ ký kỳ lạ có thể trông hơi khác so với bất cứ thứ gì bạn sử dụng.

functionName (param1: Loại, param2: Loại) => Loại

Chữ ký cho đôi là:

nhân đôi (x: n) => Số

Mặc dù thực tế là JavaScript không yêu cầu phải chú thích chữ ký, biết chữ ký là gì và ý nghĩa của chúng vẫn sẽ rất quan trọng để truyền đạt hiệu quả về cách sử dụng các chức năng và cách các chức năng được tạo ra. Hầu hết các tiện ích thành phần chức năng có thể tái sử dụng yêu cầu bạn chuyển các hàm có chung chữ ký loại.

Giá trị tham số mặc định

JavaScript hỗ trợ các giá trị tham số mặc định. Hàm sau hoạt động giống như một hàm nhận dạng (một hàm trả về cùng giá trị mà bạn truyền vào), trừ khi bạn gọi nó không xác định hoặc đơn giản là không chuyển đối số nào - thay vào đó, nó trả về 0, thay vào đó:

const orZero = (n = 0) => n;

Để đặt mặc định, chỉ cần gán nó cho tham số với toán tử = trong chữ ký hàm, như trong n = 0, ở trên. Khi bạn gán các giá trị mặc định theo cách này, hãy nhập các công cụ suy luận như Tern.js, Flow hoặc TypeScript có thể tự động suy ra chữ ký loại của hàm của bạn, ngay cả khi bạn không khai báo rõ ràng các chú thích loại.

Kết quả là, với các plugin phù hợp được cài đặt trong trình soạn thảo hoặc IDE của bạn, bạn sẽ có thể thấy các chữ ký hàm được hiển thị nội tuyến khi bạn gọi các hàm gọi. Bạn cũng có thể hiểu cách sử dụng chức năng trong nháy mắt dựa trên chữ ký cuộc gọi của nó. Sử dụng các bài tập mặc định bất cứ nơi nào có ý nghĩa có thể giúp bạn viết thêm mã tự viết.

Lưu ý: Các tham số có giá trị mặc định don không được tính vào thuộc tính hàm .length, chức năng này sẽ loại bỏ các tiện ích như autocurry phụ thuộc vào giá trị .length. Một số tiện ích cà ri (chẳng hạn như lodash / cà ri) cho phép bạn vượt qua một arity tùy chỉnh để khắc phục giới hạn này nếu bạn va vào nó.

Đối số được đặt tên

Các hàm JavaScript có thể lấy các ký tự đối tượng làm đối số và sử dụng phép gán hủy trong chữ ký tham số để đạt được tương đương với các đối số được đặt tên. Lưu ý, bạn cũng có thể gán giá trị mặc định cho tham số bằng tính năng tham số mặc định:

const createdUser = ({
  tên = 'Ẩn danh',
  avatarThumbnail = '/avatars/anonymous.png'
}) => ({
  Tên,
  avatarThumbnail
});
const george = createdUser ({
  tên: 'George',
  avatarThumbnail: 'avatar / sắc thái-emoji.png'
});
hẻm núi;
/ *
{
  tên: 'George',
  avatarThumbnail: 'avatar / sắc thái-emoji.png'
}
* /

Nghỉ ngơi và trải

Một tính năng phổ biến của các hàm trong JavaScript là khả năng tập hợp một nhóm các đối số còn lại trong chữ ký hàm bằng cách sử dụng toán tử còn lại: ...

Ví dụ, hàm sau chỉ cần loại bỏ đối số đầu tiên và trả về phần còn lại dưới dạng một mảng:

const aTail = (đầu, ... đuôi) => đuôi;
aTail (1, 2, 3); // [2, 3]

Phần còn lại tập hợp các yếu tố riêng lẻ lại với nhau thành một mảng. Lan truyền làm ngược lại: nó lây lan các phần tử từ một mảng sang các phần tử riêng lẻ. Xem xét điều này:

const shiftToLast = (đầu, ... đuôi) => [... đuôi, đầu];
shiftToLast (1, 2, 3); // [2, 3, 1]

Mảng trong JavaScript có một trình vòng lặp được gọi khi toán tử trải được sử dụng. Đối với mỗi mục trong mảng, iterator cung cấp một giá trị. Trong biểu thức, [... đuôi, đầu], trình vòng lặp sao chép từng phần tử theo thứ tự từ mảng đuôi vào mảng mới được tạo bởi ký hiệu nghĩa đen xung quanh. Vì phần đầu đã là một phần tử riêng lẻ, chúng tôi chỉ cần đặt nó vào phần cuối của mảng và chúng ta đã hoàn thành.

Cà ri

Hàm curried là một hàm lấy nhiều tham số cùng một lúc: Nó lấy một tham số và trả về một hàm lấy tham số tiếp theo, và cứ thế cho đến khi tất cả các tham số được cung cấp, tại đó, ứng dụng được hoàn thành và giá trị cuối cùng được trả lại.

Curry và một phần ứng dụng có thể được kích hoạt bằng cách trả về một chức năng khác:

const highpass = cutoff => n => n> = cutoff;
const gt4 = đường cao tốc (4); // highpass () trả về một hàm mới

Bạn don lồng phải sử dụng các chức năng mũi tên. JavaScript cũng có một từ khóa chức năng. Chúng tôi đang sử dụng các hàm mũi tên vì từ khóa hàm được gõ nhiều hơn. Điều này tương đương với định nghĩa highPass (), ở trên:

const highpass = chức năng highpass (cắt) {
  hàm trả về (n) {
    trả về n> = cắt;
  };
};

Mũi tên trong JavaScript đại khái có nghĩa là chức năng. Có một số khác biệt quan trọng trong hành vi chức năng tùy thuộc vào loại chức năng bạn sử dụng (=> thiếu chức năng này và không thể được sử dụng như một công cụ xây dựng), nhưng chúng ta sẽ có những khác biệt khi chúng ta đến đó. Hiện tại, khi bạn thấy x => x, hãy nghĩ "một hàm lấy x và trả về x". Vì vậy, bạn có thể đọc const highpass = cutoff => n => n> = cutoff; như:

Đường cao tốc là một hàm lấy điểm cắt và trả về hàm lấy n và trả về kết quả của n> = cutoff ".

Vì highpass () trả về một hàm, bạn có thể sử dụng nó để tạo một hàm chuyên biệt hơn:

const gt4 = đường cao tốc (4);
gt4 (6); // thật
gt4 (3); // sai

Autocurry cho phép bạn chức năng cà ri tự động, cho sự linh hoạt tối đa. Giả sử bạn có hàm add3 ():

const add3 = cà ri ((a, b, c) => a + b + c);

Với autocurry, bạn có thể sử dụng nó theo nhiều cách khác nhau và nó sẽ trả về điều đúng tùy thuộc vào số lượng đối số bạn truyền vào:

thêm 3 (1, 2, 3); // 6
thêm 3 (1, 2) (3); // 6
thêm 3 (1) (2, 3); // 6
thêm 3 (1) (2) (3); // 6

Xin lỗi người hâm mộ Haskell, JavaScript thiếu cơ chế tự động tích hợp sẵn, nhưng bạn có thể nhập một cơ chế từ Lodash:

$ npm cài đặt - lưu lại

Sau đó, trong các mô-đun của bạn:

nhập cà ri từ 'lodash / cà ri';

Hoặc, bạn có thể sử dụng phép thuật sau đây:

// Tự động đệ quy nhỏ
cà ri const = (
  f, mảng = []
) => (... tranh luận) => (
  a => a.length === f.length?
    f (... a):
    cà ri (f, a)
) ([... mảng, ... args]);

Thành phần chức năng

Tất nhiên bạn có thể soạn các hàm. Thành phần hàm là quá trình chuyển giá trị trả về của một hàm làm đối số cho hàm khác. Trong ký hiệu toán học:

f. g

Dịch nghĩa này trong JavaScript:

f (g (x))

Nó đánh giá từ trong ra ngoài:

  1. x được đánh giá
  2. g () được áp dụng cho x
  3. f () được áp dụng cho giá trị trả về của g (x)

Ví dụ:

const inc = n => n + 1;
inc (gấp đôi (2)); // 5

Giá trị 2 được truyền vào double (), tạo ra 4. 4 được truyền vào inc () để ước lượng thành 5.

Bạn có thể truyền bất kỳ biểu thức nào dưới dạng đối số cho hàm. Biểu thức sẽ được đánh giá trước khi chức năng được áp dụng:

inc (gấp đôi (2) * gấp đôi (2)); // 17

Vì double (2) ước tính thành 4, bạn có thể đọc rằng inc (4 * 4) ước tính thành inc (16) sau đó ước lượng thành 17.

Thành phần chức năng là trung tâm của lập trình chức năng. Chúng tôi sẽ có nhiều hơn về nó sau này.

Mảng

Mảng có một số phương pháp tích hợp. Phương thức là một hàm được liên kết với một đối tượng: thường là một thuộc tính của đối tượng được liên kết:

const mảng = [1, 2, 3];
mảng.map (gấp đôi); // [2, 4, 6]

Trong trường hợp này, mảng là đối tượng, .map () là một thuộc tính của đối tượng có hàm cho một giá trị. Khi bạn gọi nó, hàm sẽ được áp dụng cho các đối số, cũng như một tham số đặc biệt gọi là tham số này, nó sẽ tự động được đặt khi phương thức được gọi. Giá trị này là cách .map () có quyền truy cập vào nội dung của mảng.

Lưu ý rằng chúng tôi sẽ chuyển hàm kép thành một giá trị vào bản đồ thay vì gọi nó. Đó là bởi vì bản đồ lấy một hàm làm đối số và áp dụng nó cho từng mục trong mảng. Nó trả về một mảng mới chứa các giá trị được trả về bởi double ().

Lưu ý rằng giá trị mảng ban đầu không thay đổi:

mảng; // [1, 2, 3]

Phương pháp Chaining

Bạn cũng có thể xâu chuỗi các cuộc gọi phương thức. Phương thức xâu chuỗi là quá trình gọi trực tiếp một phương thức trên giá trị trả về của hàm, mà không cần tham chiếu giá trị trả về theo tên:

const mảng = [1, 2, 3];
mảng.map (gấp đôi) .map (gấp đôi); // [4, 8, 12]

Một vị từ là một hàm trả về giá trị boolean (đúng hoặc sai). Phương thức .filter () lấy một vị từ và trả về một danh sách mới, chỉ chọn các mục vượt qua vị từ (trả về true) để được đưa vào danh sách mới:

[2, 4, 6] .filter (gt4); // [4, 6]

Thông thường, bạn sẽ muốn chọn các mục từ danh sách, sau đó ánh xạ các mục đó sang danh sách mới:

[2, 4, 6] .filter (gt4) .map (gấp đôi); [8, 12]

Lưu ý: Sau này trong văn bản này, bạn sẽ thấy một cách hiệu quả hơn để chọn và lập bản đồ cùng lúc bằng cách sử dụng một thứ gọi là đầu dò, nhưng có những thứ khác để khám phá trước.

Phần kết luận

Nếu đầu bạn quay cuồng ngay bây giờ, đừng lo lắng. Chúng tôi hầu như không làm trầy xước bề mặt của rất nhiều thứ đáng được khám phá và cân nhắc hơn nhiều. Chúng tôi sẽ quay lại và khám phá một số chủ đề này sâu hơn nhiều, sớm thôi.

Mua sách | Chỉ số |

Tìm hiểu thêm tại EricElliottJS.com

Các bài học video với các thách thức mã tương tác có sẵn cho các thành viên của EricElliottJS.com. Nếu bạn không phải là thành viên, hãy đăng ký ngay hôm nay.

Eric Elliott là một chuyên gia về hệ thống phân tán và là tác giả của các cuốn sách, Phần mềm soạn thảo phần mềm và chương trình ứng dụng JavaScript. Là người đồng sáng lập DevAnywhere.io, ông dạy các nhà phát triển các kỹ năng họ cần để làm việc từ xa và nắm lấy cân bằng công việc / cuộc sống. Ông xây dựng và tư vấn cho các nhóm phát triển cho các dự án tiền điện tử và đã đóng góp vào trải nghiệm phần mềm cho Adobe Systems, Zumba Fitness, Tạp chí Phố Wall, ESPN, BBC và các nghệ sĩ thu âm hàng đầu bao gồm Usher, Frank Ocean, Metallica và nhiều hơn nữa.

Anh thích một lối sống xa xôi với người phụ nữ đẹp nhất thế giới.