These repo contains course notes in the following courses
- Intro to JavaScript on Udacity
- Object-Oriented JavaScript from HackReactor on Udacity
- Asynchronous JavaScript Requests on Udacity
- JavaScript Promises from Google on Udacity
as well as based off of the following YouTube videos:
JavaScript OOP Crash Course by Traverse Media
Node.js crash course by Traverse Media
TypeScript crash course by Traverse Media
Learn TypeScript in 50 Minutes by Codevolution
Check out this article https://www.jianshu.com/p/c7edec329338 for details
Brief Summary:
Traditional
function()definitionsthis的binding 发生在函数实际调用的时候, 不同的函数实际调用方式, 决定了this的binding: 谁调用了这个函数,this就绑定至谁.作为function调用
this绑定至global object作为object的method调用
this绑定至该object作为constructor (function class)调用
this绑定至新创建的instance间接调用 (即通过
.call(thisArg, ...),.apply(thisArg, [...]),.bind(thisArg, ...))this绑定至.call(),.apply(),.bind()的第一个参数thisArg
Arrow functions
=>definitionsthis的binding 发生在函数定义的时候, 其被绑定至arrow function定义时的外层上下文
=> 因此, 一般在object上定义methods时:
- 要使用
function()definition, 这样才能在method实际调用的时候, 将this正确绑定至该object - 若使用了arrow function, 则
this被绑定至method定义时的外层上下文 (往往是global object), 是不对的
e.g.,
constumbrella={color: 'pink',isOpen: false,open: function(){if(this.isOpen){return'This umbrella is already open.';}else{this.isOpen=true;return'Successfully opened the umbrella!';}}// If we do the following:// open: () => {// if (this.isOpen) { // "this" binds to the outer context, which is the global object in this case, so "this.isOpen" is undefined.// return '...';// } else {// this.isOpen = true;// return '...';// }// }}umbrella.open();// "this" binds to "umbrella" object
OOP
// Define a "prototypal class", aka "functional class", which is essentially// still a functionfunctionPerson(firstName,lastName,dateOfBirth){letperson=Object.create(Person.prototype);// In this case, field lookups on a new instance will be delegated to// Person.prototype object, which should contain all of the methods of this// "functional class".// Also, note that Person.prototype.constructor refers back to Personperson.firstName=firstName;person.lastName=lastName;person.dateOfBirth=newDate(dateOfBirth);returnperson;}// Define methods onto [FunctionalClass].prototype object// => So that field lookups on a new instance will be delegated to this// [FunctionalClass].prototypePerson.prototype.getFullName=function(){return`${this.firstName}${this.lastName}`;};Person.prototype.getBirthYear=function(){returnthis.dateOfBirth.getFullYear();};// Define class static methodsPerson.topNames=()=>{return['Mark','Lily'];};
The only difference is the way in which we use the functional class:
-> This time, we use the "new" keyword, which will handle a lot of work in the previous example for us.
// Define a "prototypal class", aka "functional class", which is essentially// still a functionfunctionPerson(firstName,lastName,dateOfBirth){// Instead of using the object created manually by us, we use "this" keywordthis.firstName=firstName;this.lastName=lastName;this.dateOfBirth=newDate(dateOfBirth);}// Define methods...// Define class static methods ... // InheritancefunctionStudent(firstName,lastName,dateOfBirth,studentId){Person.call(this,firstName,lastName,dateOfBirth);// 继承propertiesthis.studentId=studentId;}// Inheritance的本质上是prototype chaining (继承methods)Student.prototype=Object.create(Person.prototype);// At this point, Student.prototype simply delegates to Person.prototype.Student.prototype.constructor=Student;// However, we must manually add the constructor property; otherwise calling "Student.prototype.constructor" would be delegated to Person.prototype, which results in Person.// (继承static methods)// 由于static methods是直接定义在了Person这个"function class"本身上的, 因此为了继承// static methods, 还需要定义"function class"本身的prototype chaining关系, 使得// Student delegates to PersonStudent.__proto__=Person;
Essentially, this is just syntax sugar, that under the hood does the same thing as previous ones.
classPerson{statictopNames(){return['Mark','Lily'];}constructor(firstName,lastName,dateOfBirth){constdob=newDate(dateOfBirth);Object.assign(this,{ firstName, lastName, dob });}getFullName(){return`${this.firstName}${this.lastName}`;}getBirthYear(){returnthis.dob.getFullYear();}}// InheritanceclassStudentextendsPerson{constructor(firstName,lastName,dateOfBirth,studentId){super(firstName,lastName,dateOfBirth);this.studentId=studentId;}getgetStudentId(){returnthis.studentId;}}
Native
XMLHttpRequestor simply"XHR", through callbacksCheck out https://github.com/Ziang-Lu/JavaScript-Learning-Notes/tree/master/ajax/1-xhr-callback
jQuery.ajax()method, through callbacksCheck out https://github.com/Ziang-Lu/JavaScript-Learning-Notes/tree/master/ajax/2-jQuery-ajax-callback
Promise-based,fetch()-APICheck out https://github.com/Ziang-Lu/JavaScript-Learning-Notes/tree/master/ajax/3-promise-fetch
Through
async/awaitsyntaxCheck out https://github.com/Ziang-Lu/JavaScript-Learning-Notes/tree/master/ajax/4-promise-fetch-async-await
This repo is distributed under the MIT license.