preface
Hello, everyone. I'm zha'er π¦ Every day πͺ , you can get a promotion and a raise π° When general manager becomes CEO, marry Bai Fumei and go to the top of life π» I'm a little excited π.
This is my 13th issue A kind of , hope to be able to explain every knowledge point clearly, (of course, if you don't know which one, you can discuss it in the comment area!) A kind of , time starts!
If you find this article helpful, please like, collect, comment and leave your footprints of learning π£ , I would like to talk about π
Don't say much, start learning!!!
I will constantly revise the content of this article. Let's discuss it together! π
Learning css layout π€£
Display attribute is the most important attribute used to control layout in css. Each element has a default display value, which is related to the type of element. The default value of most elements is generally block or inline.
- Each element has a default display
Block elements are called block level elements; inline elements are called inline elements
The commonly used display value, sometimes none, is used to hide or display without deleting elements, display:none .
display set to none does not occupy the space it should be displayed; use v isibility:hidden It will take up space, but it's hidden. The element is still there.
Position attribute: static is the default value, pithy formula, and the child is the absolute parent. Fixed, a fixed positioning element will be positioned relative to the window, even if the page scrolls, it will stay in the same position.
Float in the css attribute, float can achieve the effect of text surrounding the picture:
img { float: right; margin: 0 0 1em 1em; }
The clear attribute can be used for controlled floating elements. If a box has a float: left float added, you can use clear: left to clear the left float of the element.
Clear float, clearfix hack, you can use the new css Style:
.clearfix { overflow: auto; }
Percentage width, which is a unit of measure relative to the containing block.
.clearfix { float: right; width: 50%; } nav { float: left; width: 15%; } section { margin-left: 15%; }
Responsive design is a strategy that allows websites to "present" different display effects for different browsers and devices. It can make websites present good effects in different situations.
Inline block is an inline block label
.box { float: left; width: 200px; height: 100px; margin: 1em; } .after-box { clear: left; } // Same effect .box1 { display: inline-block; width: 200px; height: 100px; margin: 1em; }
flexbox is a new layout mode of css3, which is used to meet the complex needs of modern web.
<div class="flex-container"> <div class="flex-item">flex item 1</div> <div class="flex-item">flex item 2</div> </div> .flex-container { display: -webkit-flex; display: flex; width: 300px; height: 240px; background-color: Silver; } .flex-item { background-color: DeepSkyBlue; width: 100px; height: 100px; margin: 5px; }
JavaScript variables π
1, Int integer
2. Float
3. Boolean
4. String string
5. Array
6. Object object
7. Function function
8. Regular Expression
Hump nomenclature π
- All lowercase, words separated by underscores
- Mixed case, large hump, each word is capitalized, small hump, the first word is lowercase, the other is capitalized.
rule π
First character, English letter or underline; composition, English letter, number, underline; (disable, JavaScript keywords and reserved words)
statement π
Display declaration, use var variable name, ({no type, repeated declaration, implicit declaration, direct copy without declaration}), ({declaration first, read-write later, assignment first, operation second}).
Variable type π
The value type, which occupies a fixed space, is saved in the stack. What is saved and copied is the value itself. Use typeof to detect the type of data. The basic type of data is the value type.
The reference type is not fixed. It is saved in the heap. What is saved and copied is a pointer to the object. The instanceof is used to detect the data type. The object constructed by the new() method is a reference type.
Scope π
Global variables, including variables defined outside the function, var free variables defined inside the function; call, anywhere.
Local variables, including variables declared with var inside the function, parameter variables of the function; call, inside the current function body.
Priority: the local variable is higher than the global variable with the same name, the parameter variable is higher than the global variable with the same name, and the local variable is higher than the parameter variable with the same name.
Property: ignore the block level scope. The global variable is the attribute of the global object and the local variable is the attribute of the calling object.
Scope chain, inner function can access outer function local variables, outer function can not access inner function local variables.
Declaration cycle: global variables, except for being deleted, are always, local variables, and are declared until the function runs or is deleted. Recycling mechanism, clear marking, reference counting.
Logical operators π
! Logical non
Return true
Empty string 0 null NaN undefined
Return false
object Non empty string Non-zero value (Infinity)
Note: it is not logical and can be used twice in a row to convert any type to Boolean value
&&Logic and π
- Returns the second operand when the first operand is an object
- Returns the object when the second operand is an object and the first operand is true
- Both operands are objects, return the second operand
- Returns null when an operand is null
- When an operand is NaN, NaN is returned
- An operand is undefined, and undefined is returned
Note: when the value of the first operand is false, the second operand is not evaluated.
Logical or|| π
- The first operand is an object and returns the first operand
- The first operand is false, and the second operand is returned
- Both operands are objects, return the first operand
- Both operands are null, return null
- Both operands are NaN, return NaN
- Both operands are undefined, and undefined is returned
Note: if the first operand value is true, the second operand is not evaluated.
JavaScript array
add to
push() adds an array at the end of the array
unshift() adds elements to the array header
concat() merges two arrays
delete
pop() deletes and returns the last element of the value
shift() deletes and returns the first element of the array
Queue method (FIFO); stack method (LIFO).
splice() and slice()
splice()
- Delete any number of items: 1. The starting subscript to be deleted; 2. The number of items to be deleted
- Inserts the specified item at the specified location: 1, start subscript, 2, 0 (no item is deleted), 3, item to insert.
- Replace any number of items: 1, start subscript, 2, number of items to delete, 3, items to insert
splice() method, annotation, which changes the original array. Used to add or remove elements from an array.
arrayObject.splice(index,howmany,item1,.....,itemX) var arr = ['a', 'b', 'c'] arr.splice(2,1) // Delete an array of deleted elements ['c'] arr.splice(2,0) // Delete 0, return empty array [] var array = [1,2,3,4,5]; array.splice(3,2); console.log(array); // Results: [1,2,3] var myFish = ['angel', 'clown', 'mandarin', 'sturgeon']; var removed = myFish.splice(2); // Delete all elements starting at 2 // Myfish after operation: ["angel", "cloud"] // Deleted element: ["mandarin", "sturgeon"]
All major browsers support splice()
Array array's splice() method, which is used to delete, insert and replace
Insert usage
Syntax: array.splice(starti,0, value 1, value 2...); //Indicates where to insert, 0 indicates to delete 0 elements, because the insertion and replacement are expanded by the deletion function, with values of 1, 2 and the value to be inserted var array = [1,2,3,4,5]; array.splice(2,0,11,22); //Results: [1,2,11,22,3,4,5]
Use of substitution
grammar:array.splice(starti,n,Value 1, value 2); var array = [1,2,3,4,5]; array.splice(2,2,11,22); // Results: [1,2,11,22,5]
slice() function, select some elements from the existing array to form a new array
- Returns the starting position of an item
- Returns the end of an item
If it is a negative number, the array length plus the value is used to determine the position. The revelation position is actually the actual subscript of the array, and the actual subscript of the end position is the end value minus 1.
Array.prototype.slice()
The slice() method returns a new array object. The original array will not be changed. This object is a shallow copy of the original array determined by begin and end.
const animals = ['1', '2', '3', '4', '5']; console.log(animals.slice(2)); // expected output: Array ["3", "4", "5"] console.log(animals.slice(2, 4)); // expected output: Array ["3", "4"] console.log(animals.slice(1, 5)); // expected output: Array ["1", "2", "3", "4"]
slice(start,end), which is intercepted from start to end. The return value is the collection of intercepted elements (only a new array is returned if the elements in the original array are copied shallowly)
var fruits = ['a', 'b', 'c', 'd', 'e']; var citrus = fruits.slice(1, 3); // fruits contains ['a', 'b', 'c', 'd', 'e'] // citrus contains ['b','c']
slice method uses a class array object / collection to convert it into a new array.
function list() { return Array.prototype.slice.call(arguments); } var list1 = list(1, 2, 3); // [1, 2, 3]
In JavaScript, almost everything is an object, except for immutable primitive values like string, number, and Boolean.
Array.prototype.slice
function myFunc() { // Error, arguments is a class array object, not a real array arguments.sort(); // Using slice, a method in Array prototype // It accepts an array like object( key:value) // And return a real array var args = Array.prototype.slice.call(arguments); // args is now a real Array, so you can use the sort() method of Array args.sort(); }
Array sorting, reverse() reverses the order of the elements in the array, and sort() sorts the character array or the number array.
function compare(value1, value2) { if(value1 < value2) { return -1; }else if(value1 > value2) { return 1; }else{ return 0; } }
Array conversion
- toString() is converted to a string and returns
- toLocaleString() is converted to a local format string and returns
- join() splits the array with the specified separator and converts it to a string
The toString() function is used to return the string form of the current Object. This method belongs to an Object object Object.
Iteration method: parameters
- every returns true if the function returns true for each item
- filter returns all array members with a value of true
- forEach no return value
- map returns the result array of each function call
- some returns true if any item returns true
Receive parameters:
- Functions to run on each item
- Scope object to run the function
Incoming parameters:
- Value item of array item
- The position index of the item in the array
- Array object itself array
Reduction method:
- reduce traverses from the beginning of the array
- reduceRight traverses from the end of the array
The reduce() method takes a function as an accumulator, and each value in the array (from left to right) starts to be reduced and finally evaluates to a value.
reduce() can be used as a higher-order function for the function's compose.
Note: reduce() does not perform a callback function for an empty array.
var numbers = [1, 2, 3, 4]; numbers.reduce(Callback function);
const array1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue; // 1 + 2 + 3 + 4 console.log(array1.reduce(reducer)); // 10 // 5 + 1 + 2 + 3 + 4 console.log(array1.reduce(reducer, 5)); // 15 var arr = [1,2,3,4]; // Summation var sum = arr.reduce((x,y)=>x+y) var sum1 = arr.reduce((x,y)=>x*y)
Find the maximum value of an array item
var max = arr.reduce(function (prev, cur) { return Math.max(prev,cur); });
Take the maximum of two values and continue to the next round of adjustment.
Array de duplication
arr.reduce(function(prev,cur,index,arr){ ... }, init); arr Represents the original array; prev Represents the return value, or initial value, of the last callback call init; cur Represents the array element currently being processed; index Indicates the index of the array element currently being processed, if provided init Value, the index is 0; otherwise, the index is 1; init Represents the initial value. arr.reduce(callback,[initialValue]) initialValue (As first call callback The first parameter of.)
If this array is empty, what is the case with reduce?
var arr = []; var sum = arr.reduce(function(prev, cur, index, arr) { console.log(prev, cur, index); return prev + cur; }) //"TypeError: Reduce of empty array with no initial value" var arr = []; var sum = arr.reduce(function(prev, cur, index, arr) { console.log(prev, cur, index); return prev + cur; }οΌ0) console.log(arr, sum); // [] 0
in js, it is generally used to traverse objects and arrays
In function, judge whether the attribute exists in the object, in true, not in false.
in function, judge array, index number is property.
For an array, the elements of the array are recycled; for an object, the attributes of the object are recycled; for an object, the variables refer to the indexes of the array; for an object, the variables refer to the attributes of the object.
Count the number of occurrences of each element in the array
// Total score var scoreReport = [ { name: 'dada', score: 100 }, { name: 'Nezha the devil', score: 99 } ] // for var sum = 0 for(var i = 0; i<scoreReport.length; i++) { sum += scoreReport[i].score }
If you use reduce
var sum = scoreReport.reduce(function(prev, cur) { return cur.score + prev },0);
Vuex
Rules in Vuex can only modify data in state in transitions, and actions cannot directly modify state
establish Vuex.Store Save the instance to the variable store, and export the store using export default
import Vuex from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ }) export default store
state
Frequently written documents store.js
import Vue from 'vue' import Vuex from 'vuex' // import * as getters from './getters' Vue.use(Vuex) const state = { // Place initial state a: 123 }; const mutations = { // Place our state change function }; export default new Vuex.Store({ state, mutations, // getters })
this.$store.state
To get the defined dataimport Vuex from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 1 } }) export default store
import Vuex from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 1 }, getters: { // getters are equivalent to the computed calculation attribute in vue getStateCount: function(state){ return state.count+1; } } }) export default store
To modify the value in state, you need to submit the mutation to modify it
The getter in Vuex is just like the calculation property. The return value of getter will be cached according to its dependency, and will be recalculated only when its dependency value changes.
Getter accepts state as its first parameter:
const store = new Vuex.Store({ state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } })
When the getter is accessed through properties, it is cached as part of Vue's responsive system
When the getter is accessed through a method, it will be called every time without caching the result.
In a function{ this.$store.commit('add'); } import Vuex from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 1 }, getters: { // getters are equivalent to the computed calculation attribute in vue getStateCount: function(state){ return state.count+1; } }, mutations: { add(state) { state.count += 1; }, } }) export default store // xxx.vue {{$store.getters.getStateCount}}
Submission - object style submission method, directly using the object containing the type attribute:
store.commit({ type: 'increment', amount: 10 })
There is also an action in Vuex. This purpose is not to directly modify the value in the store as above, but to modify the status value by submitting an action, and then submitting the states in actions.
Define the functions for actions to submit the transitions first
Example:
In a function{ this.$store.dispatch('addFun') } import Vuex from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 1 }, getters: { // getters are equivalent to the computed calculation attribute in vue getStateCount: function(state){ return state.count+1; } }, mutations: { add(state) { state.count += 1; }, }, actions: { // Register actions, equivalent to methods in vue addFun(context){ // Context receives a context object with properties of the same method as the store instance context.commit('add') }, } }) export default store
Use mapState, mapGetters, mapActions instead of this$ store.state.count And this$ store.dispatch ('addfun ') this way of writing.
How to use:
import {mapState, mapGetters, mapActions} from 'vuex'; // Using computed state changes computed: { ...mapState({ countdada: state=>state.count }) } // Map getter s in the store to local calculation properties: import { mapGetters } from 'vuex' export default { // ... computed: { // Using object expansion operator to mix getter into computed object ...mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) } } ...mapGetters({ // Put` this.doneCount `Map to ` this$ store.getters.doneTodosCount ` doneCount: 'doneTodosCount' })
this in JavaScript
This, what is it? This, this keyword is executed as ThisBinding of the current execution environment.
In most cases, the way the function is called determines the value of this. This point is determined at call time, not at creation time.
// this points to global variables function dadaqianduan() { return this; } console.log(dadaqianduan() === window); // true
Use call(), apply(), this to point to the bound object.
var person = { name: 'dada', age: 12 }; function sayHello(job) { console.log(this.name + "," + this.age + "," + job); } sayHello.call(person, 'it'); // dada,12,it sayHello.apply(person, ['it']);
Arrow function, all arrow functions do not have their own this, and point to the outer layer. The arrow function captures the this value of its context as its own. (inside the function, the value of this depends on how the function is called.)
this of the arrow function always points to the object at the time of definition. Is not the object that the runtime is on.
function da() { setTimeout(()=>{ console.log('this',this.id) },1000); } da.call({id: 12});
Arrow function is located in da function. Only after da function runs, it will be generated according to the definition. so, the object where da runs is exactly the object where arrow function is defined.
(a word worth exploring), using this in the arrow function is like using ordinary variables. If you can't find it in the scope of the arrow function, you will always look for the parent scope.
this also points to global variables, as follows:
var name = 'da'; var person = { name: 'dadaqianduan', getName: function() { return this.name; } } var getName = person.getName(); console.log(getName()); // da
As a constructor, this is bound to the new object being constructed.
function Person(name) { this.name = name; this.age = 12; this.say = function() { console.log(this.name + ":" + this.age); } } var pserson = new Person('dadaqianduan'); person.say();
Several call scenarios of this:
var obj = { a: 1, b: function() { console.log(this); } }
- When called as an object, point to obj.b(); / / point to obj
- When called as a function, var b = obj.b; b(); / / points to the global window
- When called as a constructor, var b = new Fun(); // this. Points to the current instance object
- When calling object.b.apply (object, []); / / this points to the current object as call and apply
Example:
var a = dadaqianduan; var obj = { a: dada } function fun() { console.log(this.a); } fun(); // dadaqianduan fun.call(obj); // dada
function da(a,b,c) { console.log(arguments); // Use call/apply to convert arguments into an array and return the result as an array var arg = [].slice.call(arguments); } da(1,2,3)
this refers to the top-level object in the global context, non strict mode and strict mode.
this === window // true
Function context
var name = 'dadaqianduan'; var fun = function() { console.log(this.name); } fun(); // 'dadaqianduan'
The call() method calls a function with a specified this value and one or more parameters given separately.
The syntax and function of this method are similar to that of apply(), with only one difference: call() method accepts a parameter list, and apply() method accepts an array with multiple parameters.
Example:
function da(name, age) { this.name = name; this.age = age; } function dada(name, age) { da.call(this, name, age); this.job = 'it'; } console.log(new dada('dadaqianduan, 12').name); // dadaqianduan
Syntax:
function.call(thisArg, arg1, arg2, ...)
Parameter: thisArg, the value of this used when the function is running. This may not be the actual value seen by the method. arg1,arg2,... List of parameters specified.
Return value, the return value of the function is called with this value and parameters provided by the caller. If the method does not return a value, undefined is returned.
Description:
call() allows you to assign and call functions / methods belonging to one object for different objects. Provides a new this value to the currently called function / method. You can use call to implement inheritance.
Using the call method to call the parent constructor
function Person(name, age) { this.name = name; this.age = age; } function Child1(name, age) { Person.call(this, name, age); this.eat = 'beff'; } function Child2(name, age) { Person.call(this, name, age); this.eat = 'food'; } var da1 = new Child1('Nezha 1', 12); var da2 = new Child2('Nezha 2', 12);
Using call method to call anonymous function
var person = [ { name: 'da1', age: 1 }, { name: 'da2', age: 2 } ]; for(var i=0; i<person.length; i++) { (function(i){ this.fun = function() { console.log('dadaqianduan'); } this.fun(); }).call(person[i], i); }
class Person{ constructor(name) { this.name = name; } fun(){ console.log(this.name); } } let da = new Person('Dada front end'); da.fun(); // Dada front end
For arrow function call, there is no this,super,arguments,new.target Binding cannot be called with new. Without prototype object, the binding of this cannot be changed. Parameter name cannot be duplicate.
The binding object of this is bound to the newly created object, return function or object through new call. The return value is not the newly created object, but the explicit return function or object; the call of call or apply, non strict mode, is null and undefined; the function call on object, bound to this object; the call of ordinary function, strict mode, undefined.
Note: (discuss together)
You can also remember this in objects, methods (functions) in objects, and ordinary functions.
In the binding example, this points to the global object in the non strict mode, and this is bound to the undefined and implicit binding in the strict mode, obj.foo(), this in foo points to obj.
Show binding. call() or apply() methods directly specify the binding object of this. The arrow function indicates that this is determined by the outer scope.
Example:
var a = "dadaqianduan"; function foo () { console.log(this.a) } foo(); window.a = "dadaqianduan"; function foo() { console.log(this.a) } window.foo(); // dadaqianduan
Strict mode only makes this in the function point to undefined without changing this point in the global. Only var binds variables to window, while let and const do not.
let a = "dada" const b = "dada1" function foo () { console.log(this.a) console.log(this.b) } foo(); console.log(window.a) // undefined // undefined // undefined
var a = "da"; function fun() { var a = "da1"; console.log(this); // window console.log(this.a); // so, window.a -> da } fun(); // fun called by window
var a = "da"; function fun() { // this points to window var a = "da1"; function inner() { console.log(this.a); } inner(); } fun(); // da
Who finally calls the function, and the this in the function points to the nearest principle.
Example:
function fun() { console.log(this.a) } var obj = { a: 'da', fun } var a = 'da1'; obj.fun(); // da // var obj = {fun} => var obj = {fun: fun} obj object reference fun() assignment obj.fun On, called obj Object, what you print is obj In a var obj = { a: 'da', fun: function() { // this points to obj console.log(this.a) } } var a = 'da1' obj.fun()
function fun() { console.log(this.a); }; var obj = { a: 'da', fun }; var a = 'da1'; var fun1 = obj.fun; obj.fun(); // this points to obj - > Da fun1(); // point obj.fun();, but the window object is called. so, this points to window // window.fun1()
function fun() { console.log(this.a); }; var obj = { a: 'da', fun }; var a = 'da1'; var fun1 = obj.fun; var ojb1 = { a: 'da2', fun2: obj.fun }; obj.fun(); // this points to obj - > Da fun1(); // obj.fun () - > the caller is window, so, this points to window, - > DA1 obj1.fun2(); // The caller is obg1, so, this points to obg1
function fun() { console.log(this.a); }; function doFun(fn) { console.log(this); fn(); }; var obj = { a: 'da', fun }; var a = 'da1'; doFun(obj.fun); // obj.fun(); so, this in it points to window - > DA1
function fun() { console.log(this.a); }; function doFun(fn) { console.log(this); fn(); }; var obj = { a: 'da', fun } var a = 'da1'; var obj1 = { a: 'da2', doFun }; obj1.doFun(obj.fun) // Obj 1 object calls doFun(), passing parameters obj.fun , this points to obj 1 // obj.fun() print da1 //Reason: if a function is passed as an argument to another function, implicit loss will occur, that is, the callback function loses this binding. // In strict mode, it will be bound to undefined
call,apply,bind
Functions using call and apply will be executed directly. bind is to create a new function, which needs to be called manually.
Example:
function fun() { console.log(this.a); }; var obj = { a: 'da' }; var a = 'da1'; fun(); // da1 fun.call(obj); // da fun.apply(obj); // da fun.bind(obj); // Using bind to create a new function will not execute
Example:
If call,apply,bind Receive parameter is empty or nullοΌundefinedοΌThis parameter will be ignored function fun() { console.log(this.a); }; var a = 'da'; fun.call(); // da fun.call(null); // da fun.call(undefined); // da
var ojb1 = { a: 'da' }; var obj2 = { a: 'da1', fun1: function() { console.log(this.a); // da1 }, fun2: function() { setTimeout(function(){ console.log(this); // window console.log(this.a); // window.a -> da2 },0) } } var a = 'da2'; obj2.fun1(); // da1 obj2.fun2(); //
var obj1 = { a: 'da' }; var obj2 = { a: 'da1', fun1: function() { console.log(this.a); // da1 }, fun2: function() { setTimeout(function() { console.log(this); // soοΌ{a:'da'} console.log(this.a); // soοΌda }.call(obj1), 0) // Bind external object obg1 } } var a = 'da2'; obj2.fun1(); obj2.fun2(); // Using obp2.fun2.call (obg1) changes the direction of this in fun2 function
var obj1 = { a: 'da' }; var obj2 = { a: 'da1', fun1: function() { console.log(this.a); // da1 }, fun2: function() { function inner() { console.log(this); // window{...} console.log(this.a); // da2 } inner(); } } var a = 'da2'; obj2.fun1(); obj2.fun2();
function fun() { console.log(this.a); }; var obj = { a: 'da' }; var a = 'da1'; fun(); // da1 fun.call(obj); // da fun().call(obj); // When executing the function of fun() - > DA1 and the return value of the function of fun(), an error will be reported when executing. call(obj) // Return value of fun() function undefined - > return value of function. call()
function fun() { console.log(this.a); return function() { console.log(this.a); } }; var obj = { a: 'da' }; var a = 'da1'; fun(); // DA1 - > returns an anonymous function. You can use fun()(); to call an anonymous function fun.call(obj); // Da - > return anonymous function, no call fun().call(obj); // fun(), the result value da1, returns an anonymous function and binds obj, then this is bound to obj, this.a is obj. A - > the result value is da // fun().call(obj); -> da1,da
bind binding, just return a new function
Example:
function fun() { console.log(this.a); return function() { console.log(this.a); } } var obj = { a: 'da' }; var a = 'da1'; fun(); // da1 fun.bind(obj); // No execution, return a new function fun().bind(obj); // DA1 - > anonymous function binding obj, not called.
function fun() { console.log(this.a); return function() { console.log(this.a); } } var obj = { a: 'da' }; var a = 'da1'; fun.call(obj)(); // da , da1 // fun binds obj,this points to obj, anonymous function call
var obj = { a: 'da', fun: function() { console.log(this.a); return function() { console.log(this.a) } } }; var a = 'da1'; var obj1 = { a: 'da2' }; obj.fun()(); // this.a in function, this.a in anonymous function - > window obj.fun.call(obj1)(); // Bind obj 1, anonymous function returns - > window obj.fun().call(obj1); // da1, bind obj 1, so, this to obj 2
var da1 = { name: 'Nezha the devil', sayHello: function(age) { console.log(this.name + age); } }; var da2 = { name: 'Dada front end', }; da1.sayHello(12); // apply,call da1.sayHello.apply(da2, [12]); // Dada front end 12 da1.sayHello.call(da2, 12); // Dada front end 12
simulation Function.prototype.applyFun = function(context) { context.fn = this; context.fn(); // Remove function reference from context delete context.fn; } // parameter Function.prototype.applyFun = function(context) { context.fn = this; var args = arguments[1]; context.fn(args.join(',')); // join -> string // Execute this function to expand arg with the... Operator of ES6 // context.fn(...args); delete context.fn; }
var a = 'da'; function sayHello() { console.log(this.name); } sayHello.apply(null); // If null or no parameter is passed, it is regarded as pointing to window var a = 'da'; function sayHello() { console.log(this.name); } sayHello.apply(); // If null or no parameter is passed, it is regarded as pointing to window
Override properties, ES5:
var a = { name: 'da' }; a.name = 'da1'
es6 introduces a primitive data type Symbol, which represents a unique value. The Symbol function can receive a string as a parameter. The Symbol function cannot use the new command. Generating a Symbol is a value of the original type, not an object.
Example:
var s1 = Symbol(); var s2 = Symbol(); s1 === s2 // false var s1 = Symbol("foo"); var s2 = Symbol("foo"); s1 === s2 // false
When Symbol value is used as object property name, dot operator is not used.
Example:
var mySymbol = Symbol(); // The first way to write var a = {}; a[mySymbol] = 'Nezha the devil'; // The second way of writing var a = { [mySymbol]: 'Nezha the devil' }; // The third way of writing var a = {}; Object.defineProperty(a, mySymbol, { value: 'Nezha the devil' }); // All of the above results are the same a[mySymbol] // "Nezha the devil"
var a = {}; var name = Symbol(); a.name = 'da1'; a[name] = 'da2'; console.log(a.name,a[name]); //da1,da2
var obj = { a: 'da', fun: function(b) { b = b || this.a return function (c) { console.log(this.a + b + c) } } } var a = 'da1'; var obj1 = { a: 'da2' } obj.fun(a).call(obj1, 1) // obj.fun (DA1) - > DA1 is passed to parameter b, call changes this, the direction of binding object ojb1, so, this changes, this.a points to object obj 1, which is da2. // Final results, da2 da1 1 obj.fun.call(obj1)(1) // Obj1, the binding object of this in the fun function of obj, points to obj 1 // obj.fun.call (obj 1) no parameter passed, so, because B = B | this. A // so, b is (remember to bind obj 1) DA2. Finally, the anonymous function is called, and the this in the anonymous function points to window. // da1(this.a refers to window),da2,1
function fun1 () { console.log(this.a); }; var a = 'da'; var obj = { a: 'da1' } var fun2 = function() { fun1.call(obj); }; fun2(); // da1 fun2.call(window); // da1
function fun1(b) { console.log(`${this.a} + ${b}`) return this.a + b } var a = 1 var obj = { a: 3 } var fun2 = function () { return fun1.call(obj, ...arguments) } var dada = fun2(5) console.log(dada) '3 + 5' 8 // Fun2 (5) - > fun1 binding object obj, so, this.a is obj, a is 3, 5 can be brought in
function fun(item) { console.log(item, this.a); }; var obj = { a: 'Nezha the devil' }; var a = 'dada' var arr = [1,2,3]; // The second parameter of foreach, map and filter can be bound to this's arr.filter(function(i){ console.log(i, this.a); return i>2 },obj) 1 'Nezha the devil' 2 'Nezha the devil' 3 'Nezha the devil'
function da (name) { this.name = name }; var name = 'da1'; var dada = new da('da2'); console.log(dada.name) // da2 // New calls the da function, constructs a new object dada, which is bound to this in the da call
var name = 'Nezha the devil'; function fun (name) { // Constructor this.name = name; this.daFun = function () { console.log(this.name); return function () { console.log(this.name); } } } var da1 = new fun('Nezha 1'); var da2 = new fun('Nezha 2'); da1.daFun.call(da2)() da1.daFun().call(da2)
Change your mind:
var name = 'Nezha the devil'; // var da1 = new fun('nezha 1 '); var da1 = { name: 'Nezha 1', daFun: function() { console.log(this.name); return function () { console.log(this.name); } } } // var da2 = new fun('nezha 2 '); var da2 = { name: 'Nezha 2', daFun: function() { console.log(this.name); return function () { console.log(this.name); } } } da1.daFun.call(da2)() // The daFun function binds the da2, points to da2, so, this points to da2, outputs devil Na Zha 2, finally calls (), the internal return function is called by window, and prints the devil Na Zha. // Nezha the Devil 2, Nezha the devil da1.daFun().call(da2) // da1.daFun().call(da2) binds this of anonymous function to da2 // DA1. Dafun() - > Nezha 1 - > Nezha 2
Arrow function
This in the arrow function, determined by the outer scope, points to this when the function is defined, not when it is executed. (discussion)
var obj = { name: 'Nezha the devil', fun1: () => { // The direction of this is determined by the outer scope. It refers to this when the function is defined. It is window console.log(this.name) }, fun2: function() { console.log(this.name) return () => { console.log(this.name); } } } var name = 'Dada front end'; obj.fun1(); // this.name ->Dada front end, when calling, outer layer, when outer scope, window obj.fun2()(); // this.name , this.name (anonymous function) // First look obj.fun2(), and then learn obj.fun2()() // The first object obj, so that points to calling it is Nezha the devil. The anonymous function inside is the arrow function. When the arrow function points to the definition, it is determined by the outer scope of this. It can be seen that fun2 is the function, so. Then this in the anonymous function will be the same as this in fun2. It's also Nezha the devil.
var name = 'Dada front end'; var obj1 = { name: 'Nezha 1', fun: function() { console.log(this.name) } } var obj2 = { name: 'Nezha 2', fun: () => { console.log(this.name) } } obj1.fun() // By obj 1, so, Nezha 1 obj2.fun() // this definition points to the front end of window, so and dada
var name = 'Dada front end'; var obj1 = { name: 'Nezha 1', fun: function () { console.log(this.name); return function() { console.log(this.name); } } } obj1.fun()(); // Obj 1. Fun() - > Nezha the devil, call anonymous function (), the second this.name Call outer layer, so, for dada front end // Nezha the devil, front end of dada var obj2 = { name: 'Nezha 2', fun: function() { console.log(this.name); return () => { console.log(this.name); } } } obj2.fun()(); // obj2.fun() the first value is nezha2, the second arrow function. When this is defined, it points to the outer layer, that is, this, so in obj2, is nezha2 // Nezha 2, Nezha 2 var obj3 = { name: 'Nezha 3', fun: () => { console.log(this.name); return function() { console.log(this.name) } } } obj3.fun()(); // Dada front end // first this.name , the arrow function is determined by the outer scope. When it is defined, it points to window. The memory function is determined by the caller. so is also the front end of dada. var obj4 = { name: 'Nezha 4', fun: () => { console.log(this.name); return () => { console.log(this.name); } } } obj4.fun()(); // Dada front end, dada front end, when defined, not when called
var name = 'Dada front end'; function dada (name) { this.name = name; this.fun1 = function() { console.log(this.name); } this.fun2 = () => { // Pointing to the outer scope function dada console.log(this.name); } } var da2 = { name: 'da2', fun2: () => { console.log(this.name); } } var da1 = new dada('Nezha the devil'); da1.fun1(); // The devil Na Zha, the ordinary function, the caller is dada, (determined by the last caller's object). da1.fun2(); // Nezha, arrow function, determined by outer scope, when function is defined // The outer scope is function dada, constructor and new to generate object da1, which points to dada da2.fun2(); // The scope of da2 is under window. so, build vomit function. this points to window
var name = 'Dada front end', function dada(name) { this.name = name; this.fun1 = function() { // Ordinary function console.log(this.name); // Dada return function() { // Anonymous function console.log(this.name); // Dada front end } } this.fun2 = function() { // Ordinary function console.log(this.name); // Dada return () => { // Arrow function console.log(this.name); // Determined by the outer layer, the outer layer is the dada function, whose value is dada } } this.fun3 = () => { // Arrow function console.log(this.name); // Outer layer decision, dada, so, dada return function() { // Ordinary function console.log(this.name) // Determined by the caller, da1.foo3() returns a normal function. The outer literal of the caller is da1. In window, so, dada front end } } this.fun4 = () => { // Arrow function console.log(this.name); // When defined, this points to the outer layer, dada return () => { // Arrow function console.log(this.name); // Point to the outer layer, dada } } } var da1 = new dada('Dada'); da1.fun1()(); // Dadadada front end da1.fun2()(); // Dadadada da1.fun3()(); // Dadadada front end da1.fun4()(); // Dadadada
This in the arrow function cannot be modified directly by the bind, call, and apply functions. It can be modified by changing the direction of this in the scope.
Example:
var name = 'Dada front end'; var obj1 = { name: 'Dada 1', fun1: function() { // Ordinary function console.log(this.name); return () => { // Arrow function console.log(this.name); } }, fun2: () => { // Arrow function console.log(this.name); return function() { // Ordinary function console.log(this.name); } } } var obj2 = { name: 'Dada 2' }; obj1.fun1.call(obj2)() // . call binds object obp2, the first () runs, dada2, and the second (), arrow function. this is the same in the outer fun1 ordinary function, so, dada2 // Dada 2 dada 2 obj1.fun1().call(obj2) // The first call to obj 1, dada 1, returns the arrow function. Call to bind obj 2, wants to change the direction of this to obj 2, but it is invalid, because it is determined by the definition. The execution of this or obj 1, so, output dada 1 // Dada 1 dada 1 obj1.fun2.call(obj2)() // The literal quantity of obj 1,. Call binding obj 2 is invalid. The first one is arrow function, outer scope window, dada front end, dada front end, obj 1.fun2.call (obj 2) points to outer window // Dada front end obj1.fun2().call(obj2) // First layer, arrow function, second layer, ordinary function, the first layer is directly the outer scope window, dada front end // The second layer is bound with obj 2, so and dada 2 // Dada front end, dada 2
Note: the scope of the literal object is window. If it is an arrow function, this points to window
Example:
var name = 'Dada front end'; var da1 = { name: 'dada1', fun1: function() { // Ordinary function console.log(this.name); }, fun2: () => console.log(this.name); // Arrow function fun3: function() { // Ordinary function return function() { // Anonymous function console.log(this.name); } }, fun4: function() { // Ordinary function return () => { // Arrow function console.log(this.name); } } } var da2 = { name: 'dada2' }; da1.fun1(); // Literal da1, ordinary function, caller da1, so, pointing to da1, dada1 // dada1 da1.fun1.call(da2); // this.name Bind da2,so,dada2 through. call // dada2 da1.fun2(); // Arrow function, pointing to window, so, dada front end // Dada front end da1.fun2.call(da2); // . call wants to change the direction, but it doesn't work, dada front end // Dada front end da1.fun3()(); // Anonymous function, pointing to window, dada front end da1.fun3.call(da2); // Return anonymous function, point to window, dada front end da1.fun3().call(da2); // da1.fun3() // Bind da2 through. call, return this normal function, bind da2, so,dada2 // () { console.log(this.name) } // // dada2 // function() { // Ordinary function return function() { // Anonymous function console.log(this.name); } }, // da1.fun4()(); // When this points to definition, da1, so, dada1 // dada1 da1.fun4.call(da2)(); // If a fun4 is bound to da2 and then runs (), then the return arrow function} in function() {is bound; the outer function is bound to point to da2 and dada2 // dada2 da1.fun4().call(da2); // When defined, fun4() runs, this.name Return to dada1 in // dada1
var name = 'Dada front end'; function dada(name) { this.name = name; this.fun1 = function() { console.log(this.name); }, this.fun2 = () => console.log(this.name), this.fun3 = function() { return function() { console.log(this.name) } }οΌ this.fun4 = function() { return () => { console.log(this.name) } } } var da1 = new dada('1'); var da2 = new dada('2'); da1.fun1(); // new binds dada, 1 da1.fun1.call(da2); // Binding da2, 2 da1.fun2(); // Arrow function, outer layer or dada, new dada binding dada, 1 da1.fun2.call(da2); // . call wants to change this direction, but it is not valid for arrow function, 1 da1.fun3()(); // Return a normal function, this points to window, dada front end da1.fun3.call(da2)(); // Bind da2, but it also points to window and dada front end da1.fun3().call(da2); // Bind da2, return to run (), bind da2, this to da2, 2 // da1.fun3() Ζ () { console.log(this.name) } // da1.fun4()(); // Return arrow function, call da1, point to outer da1, 1 // da1.fun4(); // ->Back () => { console.log(this.name) } da1.fun4.call(da2)(); // . call() binds da2, calls (), and the outer layer changes to da2, 2 da1.fun4().call(da2); // da1.fun4(); // ->Back () => { console.log(this.name) } // When defined, points to da1, new dada('1 ') new object, so, is 1
var name = 'Dada front end' function Person (name) { this.name = name this.obj = { name: 'obj', fun1: function () { return function () { console.log(this.name) } }, fun2: function () { return () => { console.log(this.name) } } } } var da1 = new Person('1') var da2 = new Person('2') da1.obj.fun1()(); // this refers to the outer window, and the anonymous function refers to the window da1.obj.fun1.call(da2)(); // The front-end of dada calls ordinary functions, the binding changes the first level function this, and the anonymous function in da2 points to the outer window da1.obj.fun1().call(da2); // 2. Run the fun1() normal function, return the anonymous function, bind da2, and change this, so in the anonymous function to 2 da1.obj.fun2()(); // Obj, the return arrow function in the ordinary function, obj, so when this points to when the arrow function is defined, return the this.name Obj da1.obj.fun2.call(da2)(); // 2 fun2, for function() {...}, binding, changing this of the first layer, pointing to da2, so, 2 da1.obj.fun2().call(da2); // Invalid obj arrow function, so, obj
function fun() { console.log(this.a); // this.a outer window, da }; var a = 'da'; (function(){ // This here points to window. In the following use strict strict mode, this is undefined 'use strict'; fun(); // Normal function call / / da // this.fun(); in this case, an error will be reported })();
Direction of this
Example:
function dada() { this.a = 'da'; // this points to window, under which window. A ='Da ' console.log(this.a); // window.a } dada(); // da
this in function dada, determined when the function is called, points to the current running environment of the function
Example:
var a = 'da'; function da() { console.log(this.a); }; var obj = { a: 'da1', fun: da }; obj.fun(); // da1
Object method call, pointing to obj
call simulation implementation
Example:
var obj = { name: 'dada' }; function fun() { console.log(this.name); // window.name }; fun.call(obj); // Bind this object obj, dada
// Imagine a change var obj = { // object name: 'dada', // attribute fun: function() { // Ordinary function console.log(this.name); // obj.fun() - object obj calls fun() dada } }
obj.fun = Function (assign a function)// Set function as object property obj.fun() delete obj.fun This property var obj = { name: 'dada' }; function fun() { console.log(this.name); // window.name }; fun.call(obj); // Bind this object obj, dada
Look at the above and write the following:
Function.prototype.myCall = function(An object context) { context.fun = this; // This in this step refers to the dada() function context.fun(); delete context.fun; } var obj = { name: 'dada' }; function dada() { console.log(this.name); }; dada.myCall(obj); // Object obj, bind this object, this, context.fun = this
// Analog parameter transfer problem call var obj = { value: 'dada' }; function fun(name, age) { console.log(name) console.log(age) console.log(this.value); } fun.call(obj, 'da', 12); // da // 12 // dada
arguments are class array objects
have a look arguments arguments = { 0: obj, 1: 'da', 2: 12, length: 3 }
The next step is to take out the parameters:
Call the original method, the call is separate
JavaScript eval() function
Definition and Usage
The eval() function evaluates the JavaScript string and executes it as script code.
If the argument is an expression, the eval() function executes the expression. If the argument is a Javascript statement, Eval () executes the Javascript statement.
eval(string)
Function.prototype.myCall = function(context) { context.fun = this; var args = []; for(var i = 1, len = arguments.length; i < len; i++) { args.push('arguments[' + i + ']'); } eval('context.fun(' + args +')'); delete context.fun; }
Note: the parameter can be null
var name = 'dada'; function fun() { console.log(this.name); } fun.call(null); // this points to window, dada
so change it
Function.prototype.myCall = function (context) { var context = context || window; context.fun = this; var args = []; for(var i = 1, len = arguments.length; i < len; i++) { args.push('arguments[' + i + ']'); } var result = eval('context.fun(' + args +')'); delete context.fun return result; }
apply simulation implementation
Example:
Pass in an object, and an array //Code from @ Nuggets Function.prototype.apply = function (context, arr) { var context = Object(context) || window; context.fn = this; var result; if (!arr) { result = context.fn(); } else { var args = []; for (var i = 0, len = arr.length; i < len; i++) { args.push('arr[' + i + ']'); } result = eval('context.fn(' + args + ')') } delete context.fn return result; }
bind Simulation Implementation
bind binding function, feature, return a function, parameter can be passed
Example:
var obj = { name: 'da'; }; function fun() { console.log(this.name); } // Returns a function var da1 = fun.bind(obj); da1(); // da
Bind() method creates a new function. When bind() is called, this of the new function is pointed to the first parameter of bind(), binding object, and other parameters will be parameters of the new function.
Bind changes the direction of this function, but instead of executing the function immediately, bind returns a new function bound to this.
Simulation Implementation:
The first step of simulation implementation:
Function.prototype.myBind = function(context){ var that = this return function(){ return that.apply(context) } } // Writing method 2 Function.prototype.bind_ = function (obj) { var fn = this; return function () { fn.apply(obj); }; };
The second step of simulation implementation: support function parameter transfer
Function.prototype.myBind = function (context) { var that = this; // function var args = Array.prototype.slice.call(arguments, 1); return function () { var bindArgs = Array.prototype.slice.call(arguments); return that.apply(context,args.concat(bindArgs)); } } // Writing method 2 Function.prototype.bind_ = function (obj) { // 0 is this, so start from the first var args = Array.prototype.slice.call(arguments, 1); var fn = this; return function () { fn.apply(obj, args); }; }; Function.prototype.bind_ = function (obj) { var args = Array.prototype.slice.call(arguments, 1); var fn = this; return function () { // Secondary call var params = Array.prototype.slice.call(arguments); fn.apply(obj, args.concat(params)); }; };
Add this judgment and prototype inheritance
Function.prototype.bind_ = function (obj) { var args = Array.prototype.slice.call(arguments, 1); var fn = this; var instanceObj = function () { var params = Array.prototype.slice.call(arguments); // Judging the calling mode by constructor // true this points to an instance, otherwise obj fn.apply(this.constructor === fn ? this : obj, args.concat(params)); }; //Prototype chain inheritance instanceObj.prototype = fn.prototype; return instanceObj; };
Simulation implementation revision:
Function.prototype.bind = Function.prototype.bind || function (context) { var me = this; var args = Array.prototype.slice.call(arguments, 1); var F = function () {}; F.prototype = this.prototype; var bound = function () { var innerArgs = Array.prototype.slice.call(arguments); var finalArgs = args.concat(innerArgs); return me.apply(this instanceof F ? this : context || this, finalArgs); } bound.prototype = new F(); return bound; } // modify Function.prototype.myBind = function(obj) { // It must be a function to call the bind method if(typeof this !== "function") { throw new Error('error') }; var args = Array.prototype.slice.call(arguments, 1); var fn = this; var fn_ = function () {}; var instanceObj = function () { var params = Array.prototype.slice.call(arguments); fn.apply(this.constructor === fn ? this : obj, args.concat(params)); console.log(this); }; fn_.prototype = fn.prototype; instanceObj.prototype = new fn_(); return instanceObj; };
See this realization: (discuss together, you can write an article to show me)
bind: function bind(that) { var target = this; if (!isCallable(target)) { throw new TypeError('Function.prototype.bind called on incompatible ' + target); } var args = array_slice.call(arguments, 1); var bound; var binder = function () { if (this instanceof bound) { var result = target.apply( this, array_concat.call(args, array_slice.call(arguments)) ); if ($Object(result) === result) { return result; } return this; } else { return target.apply( that, array_concat.call(args, array_slice.call(arguments)) ); } }; var boundLength = max(0, target.length - args.length); var boundArgs = []; for (var i = 0; i < boundLength; i++) { array_push.call(boundArgs, '$' + i); } bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder); if (target.prototype) { Empty.prototype = target.prototype; bound.prototype = new Empty(); Empty.prototype = null; } return bound; }
extend
Documents on MDN:
The bind() method creates a new function, when called, sets its this keyword to the provided value, when calling the new function, provides the given parameter sequence before any provision
The apply() method calls a function with a specified this reference and the parameters provided as an array
es6 mode, example:
Function.protype.myCall = function(context) { var context = context || window; context.fun = this; var args = []; for(var i=1, len = arguments.length; i<len; i++) { args.push(arguments[i]); } context.fun(...args) delete context.fun }
Function.prototype.myCall = function(context,...args) { context = context || window; context.fun = this; let temp = context.fun(...args); delete context.fun; return temp; }
Note: never use eval!
new() in js
Please tell me what you did with the new operator in js
1. Create an empty object
2. Link to prototype
3. Bind this point, execute constructor
4. Make sure the object is returned
Example:
var obj = new da(); var obj = {}; obj.__proto__ = da.prototype; da.call(obj);
function A(){} var a = new A(); a.__proto__ === A.prototype //true // Prototype chain A.__proto__ === Function.prototype //true
Add: prototype and__ proto__
Each function has a prototype property, and each object instantiated by the function contains an implicit pointer (__ proto__) The prototype property pointing to the function
new operator
- Create an empty JavaScript object {}
- Link this object to another
- Make the newly created object the context of this
- If the function does not return an object, this is returned
Example:
function da(name, age, year) { this.name = name; this.age = age; this.year = year; } const da1 = new da('dada', '12', 2333); console.log(da1.name); // expected output: "dada"
function create(){ // Create an empty object let obj = new Object(); // Get constructor let Constructor = [].shift.call(arguments); // Link to prototype obj.__proto__ = Constructor.prototype; // Bind this let result = Constructor.apply(obj,arguments); // Return to new object return typeof result === "object" ? result : obj; // let obj = new Object(); }
Object.create Simulation Implementation of:
Object.create = function( o ) { function f(){} f.prototype = o; return new f; };
reference
If you look at it quietly, you will surely get something!
Using call and apply to simulate the bind method of ES5
[suggestions π ]Another 40 interview questions of this continue (1.2w words by hand)
JavaScript in-depth call and apply simulation implementation
The simulation implementation of bind in JavaScript
Interviewer: can you simulate the bind method of JS
about
Author: he often wanders in the front-end Jianghu.
Personal blog
github blog , find a star^_ ^
WeChat official account dada front end
Perhaps the more interesting WeChat official account is long. You can also add the wechat xiaoda0423, indicate the source, and pull you into the [dada front-end communication group]. -Indicate source