<function decoration/statment>

function greet(){
    //do somthing
    console.log('hello');
} 
greet();

for (let i=0; i<50; i++){
    funcName();
}


// dice roll function
function rollDi(){
    let roll = Math.floor(Math.random()*6)+1;
    console.log(`Rolled: ${roll}`);
}
rollDi();

function throwDice(){
    rollDi();
    rollDi();
    rollDi();
    rollDi();
}

 

 

 

<funtion argument>

: 변수를 받아들이는 함수

//no inputs
'hello'.toUpperCase();

//argumets
'hello'.indexOf('h'); //0
'hello'.indexOf('o'); //4


//greet take2
function greet(person){
    console.log(`Hi, ${person}!`);
}
greet('Ned');
greet('Maria');

// dice roll function 2
function rollDi(){
    let roll = Math.floor(Math.random()*6)+1;
    console.log(`Rolled: ${roll}`);
}


function throwDice(numRolls){
    for(let i =0; i<numRolls; i++){
       rollDi();
    }
}

 

 

 

<function w/ multiple arguments>

function square(num, num2){
    console.log(num*num2);
}

function sum(x, y){
    console.log(x + y);
}

function div(a, b){
    console.log(a / b);
}

 

 

 

<return statment>

: return statment is function execution AND specifies VALUE TO BE RETURNED!!!

function add(x, y){
    return x + y;// 리턴문이 실행되는 즉시 이 코드는 여기에서 멈춤
    console.log('all done');//<- this code is NOT gonna be worked.
}
const total = add(4,5);
total; //9


//v1
function isPurple(color){
    if(color.toLowerCase() === 'purple'){
        return true;
    }else{
        return false;
    }
}

//v2
function isPurple(color){
    if(color.toLowerCase() === 'purple'){
        return true;
    } 
    return false;
}

//v3
function isPurple(color){
    return color.toLowerCase() === 'purple'; //boolean statment
}




function containsPurple(arr){
    for(let color of arr){
        if(color === 'purple' || color === 'magenta'){
            return true;
        }
        //return false;// 이지점에서는 루프를 한번만 돌았기 때문에 모든 배열에 퍼플이나 마젠타가 있는지 확인불가능
    }
    return false;// 때문에 모든 루프가 끝난 이지점에서 리턴을 선언해야함
}

 

 

 

<Practice>

 

//write function to check valid password

// over 8 characters

// not have space

// not have username

//v1
function isValidPassword(password, username) {
    if (password.length < 8) {
        return false;
    }
    if (password.indexOf(' ') !== -1) {
        return false;
    }
    if (password.indexOf(username) !== -1) {
        return false;
    }
    return true;
}

//v2
function isValidPassword(password, username) {
    if (
        password.length < 8 ||
        password.indexOf(' ') !== -1 ||
        password.indexOf(username) !== -1
    ) {
        return false;
    }
    return true;
}

//v3
function isValidPassword(password, username) {
    const tooShort = password.length < 8;
    const hasSpace = password.indexOf(' ') !== -1;
    const hasUsername = password.indexOf(username) !== -1;
    if (tooShort || hasSpace || hasUsername) return false;
    return true;
}

//v4
function isValidPassword(password, username) {
    const tooShort = password.length < 8;
    const hasSpace = password.indexOf(' ') !== -1;
    const hasUsername = password.indexOf(username) !== -1;
    return !tooShort && !hasSpace && !hasUsername;
}

 

 

// wirte a function to find the avg value in array of numbers

function getAvg(arr) {
    let total = 0;
    for (let num of arr) {

        total += num;
    }
    let avg = total / arr.length;
    return avg;
}

 

 

// isPangram

function isPangram(sen) {
    let lowerCased = sen.toLowerCase();
    for (let char of 'abcdefghijklmnopqrstuvwxyz') {
        if (lowerCased.indexOf(char) === -1) {
            return false;
        }
    }
    return true;
}

 

 

// random card select

function pick(arr) {
    let rdPick = Math.floor(Math.random() * arr.length);
    return arr[rdPick];
}

function getCard() {
    const num = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
    let rdNum = pick(num);
    const sign = ['hearts', 'spades', 'clubs', 'diamonds'];
    let rdSign = pick(sign);

    console.log(`{${rdNum}, ${rdSign}}`);

}

 

BLOCK and IIFE 

// ES6
{
    const a =1;
    let b = 2;
}
console.log(a + b); // output// Uncaught ReferenceError: a is not define

// => it is easy to manage data privacy. no need to write IIFE to just give privacy to the var.


// ES5
(function(){
    var c = 3;
})();
console.log(c); 

 

 

 

STRINGS

let firstName = 'John';
let lastName = 'Smith';
const yearOfBirth = 1990;

function calcAge(year){
    return 2016 - year;
}

// ES5
console.log('This is '+firstName+ ' '+lastName+'. He was born in '+yearOfBirth+'. Today, He is '+calcAge(yearOfBirth)+' years old.');

// ES6
console.log(`This is ${firstName} ${lastName}. He was born in ${yearOfBirth}. Today, He is ${calcAge(yearOfBirth)} years old.`);

const name = `${firstName} ${lastName}`;

console.log(name.startsWith('J')); //true
console.log(name.startsWith('j')); //false
console.log(name.endsWith('th')); //true
console.log(name.endsWith('Sm')); //false
console.log(name.includes(' ')); //true // name ='John Smith'
console.log(name.includes('oh')); //true

console.log(firstName.repeat(5)); //output//JohnJohnJohnJohnJohn
console.log(`${firstName}`.repeat(5)); //output//John John John John John

 

 

 

ARROW FUNCTION

const years = [1990, 1965, 1982, 1937];

//ES5 
var ages5 = years.map(function(el){
    return 2016 - el;
});
console.log(ages5); //output//[26, 51, 34, 79]



// ES6
let ages6 = years.map(el => 2016-el); 
console.log(ages6); //output//[26, 51, 34, 79] : get same result with less code!


ages6 = years.map((el, index)=>`Age element ${index+1}: ${2016-el}.`);
console.log(ages6); 
//output//  ["Age element 1: 26.", "Age element 2: 51.", "Age element 3: 34.", "Age element 4: 79."]


ages6 = years.map((el, index)=> {
    const now = new Date().getFullYear();
    const age = now - el;
    return `Age element ${index + 1}: ${age}.`
});
console.log(ages6);
//output// ["Age element 1: 30.", "Age element 2: 55.", "Age element 3: 38.", "Age element 4: 83."]

 

 

 

ARROW FUNCTION 2

// ES5
/*
var box5 = { 
    color: 'green',
    position: 1,
    clickeMe: function(){//this is regular function, it is not point this obj, this is point WINDOW obj
        document.querySelector('.green').addEventListener('click', function(){
            var str = 'this is box number '+this.position+' and it is '+ this.color;
            alert(str)
        });
    }
}
box5.clickeMe(); //output// undefine. box5 doesn't get any click event.
*/

var box5 = { 
    color: 'green',
    position: 1,
    clickeMe: function(){
        var self = this;
        document.querySelector('.green').addEventListener('click', function(){
            var str = 'this is box number '+self.position+' and it is '+ self.color;
            alert(str);
        });
    }
}
box5.clickeMe();


// ES6
const box6 = { 
    color: 'green',
    position: 1,
    clickeMe: function(){
       
        document.querySelector('.green').addEventListener('click', ()=> {
            var str = 'this is box number '+this.position+' and it is '+ this.color;
            alert(str);
        });
    }
}
box6.clickeMe(); // working fine!

/*
const box66 = { 
    color: 'green',
    position: 1,
    clickeMe: () => { //CUZ this is also point WINDOW!
       
        document.querySelector('.green').addEventListener('click', ()=> {
            var str = 'this is box number '+this.position+' and it is '+ this.color;
            alert(str);
        });
    }
}
box6.clickeMe(); //output// undefine. box66 doesn't get any click event.
*/




function Person(name) {
    this.name =name;
}

// ES5
Person.prototype.myFriends5 = function(friends){
    var arr = friends.map(function(el){
        return this.name + ' is friends of '+el;    
    }.bind(this)); // 바인드가 없을시 this는 윈도우를 가르키기때문에 바인드를 이용해 안에서 this를 재정의 해야함
    console.log(arr);
}
var friends = ['Bob', 'Jane', 'Mark'];
new Person('John').myFriends5(friends);


// ES6
Person.prototype.myFriends6 = function(friends){
    var arr = friends.map(el => 
        `${this.name} is friends of ${el}`);
    console.log(arr);
}
new Person('Mike').myFriends6(friends);

 

 

 

DESTRUCTURING

: ES6에서는 배열과 오브젝트에 개별적으로 접근 가능

// ES5
var john = ['John', 26];
var name = john[0];
var age = john[1];

// ES6
const [name, age] = ['John', 26];
console.log(name);
console.log(age);


//--
const obj = {
    firstName: 'John',
    lastName: 'Smith'
};
//console.log(firstName);
//console.log(lastName);//->these are not worked.

const {firstName, lastName} = obj; // after this
console.log(firstName);
console.log(lastName); //output// John Smith //these are worked!

const {firstName: a, lastName: b} = obj;
console.log(a);
console.log(b); //output// John Smith


//--
function calcRetirement(year){
    const age = new Date().getFullYear() - year;
    return [age, 65-age];
}

const [age2, retirement] = calcRetirement(1990);
console.log(age2); //output//26
console.log(retirement); //output// 39

 

 

 

ARRAY

const boxes = document.querySelectorAll('.box');


//ES5
var boxesArr5 = Array.prototype.slice.call(boxes);
boxesArr5.forEach(function(cur) {
    cur.style.backgroundColor = 'dodgerblue';
});


//ES6
const boxesArr6 = Array.from(boxes);
Array.from(boxes).forEach(cur => cur.style.backgroundColor = 'dodgerblue');


//ES5
for(var i = 0; i < boxesArr5.length; i++) {
    
    if(boxesArr5[i].className === 'box blue') {
        continue;
    }    
    boxesArr5[i].textContent = 'I changed to blue!';
}


//ES6
for (const cur of boxesArr6) {
    if (cur.className.includes('blue')) {
        continue;
    }
    cur.textContent = 'I changed to blue!';
}


//ES5
var ages = [12, 17, 8, 21, 14, 11];

var full = ages.map(function(cur) {
    return cur >= 18;
});
console.log(full);

console.log(full.indexOf(true));
console.log(ages[full.indexOf(true)]);


//ES6
console.log(ages.findIndex(cur => cur >= 18));
console.log(ages.find(cur => cur >= 18));

 

 

 

Spread Operator

function addFourAges (a, b, c, d) {
    return a + b + c + d;
}

var sum1 = addFourAges(18, 30, 12, 21);
console.log(sum1);


//ES5
var ages = [18, 30, 12, 21];
var sum2 = addFourAges.apply(null, ages);
console.log(sum2);


//ES6
const sum3 = addFourAges(...ages);
console.log(sum3);

const familySmith = ['John', 'Jane', 'Mark'];
const familyMiller = ['Mary', 'Bob', 'Ann'];
const bigFamily = [...familySmith, 'Lily', ...familyMiller];
console.log(bigFamily);


const h = document.querySelector('h1');
const boxes = document.querySelectorAll('.box');
const all = [h, ...boxes];

Array.from(all).forEach(cur => cur.style.color = 'purple');

 

 

 

Rest Parameters

//ES5
function isFullAge5() {
    console.log(arguments);
    var argsArr = Array.prototype.slice.call(arguments);
    
    argsArr.forEach(function(cur) {
        console.log((2016 - cur) >= 18);
    })
}

isFullAge5(1990, 1999, 1965);
isFullAge5(1990, 1999, 1965, 2016, 1987);


//ES6
function isFullAge6(...years) {
    years.forEach(cur => console.log( (2016 - cur) >= 18));
}

isFullAge6(1990, 1999, 1965, 2016, 1987);


//ES5
function isFullAge5(limit) {
    var argsArr = Array.prototype.slice.call(arguments, 1);

    argsArr.forEach(function(cur) {
        console.log((2016 - cur) >= limit);
    })
}

isFullAge5(16, 1990, 1999, 1965);
isFullAge5(1990, 1999, 1965, 2016, 1987);


//ES6
function isFullAge6(limit, ...years) {
    years.forEach(cur => console.log( (2016 - cur) >= limit));
}

isFullAge6(16, 1990, 1999, 1965, 2016, 1987);

 

 

 

Default Parameters

//ES5
function SmithPerson(firstName, yearOfBirth, lastName, nationality) {
    
    lastName === undefined ? lastName = 'Smith' : lastName = lastName;
    nationality === undefined ? nationality = 'american' : nationality = nationality;
    
    this.firstName = firstName;
    this.lastName = lastName;
    this.yearOfBirth = yearOfBirth;
    this.nationality = nationality;
}


//ES6
function SmithPerson(firstName, yearOfBirth, lastName = 'Smith', nationality = 'american') {
    this.firstName = firstName;
    this.lastName = lastName;
    this.yearOfBirth = yearOfBirth;
    this.nationality = nationality;
}


var john = new SmithPerson('John', 1990);
var emily = new SmithPerson('Emily', 1983, 'Diaz', 'spanish');

 

 

 

Maps

const question = new Map();
question.set('question', 'What is the official name of the latest major JavaScript version?');
question.set(1, '//ES5');
question.set(2, '//ES6');
question.set(3, 'ES2015');
question.set(4, 'ES7');
question.set('correct', 3);
question.set(true, 'Correct answer :D');
question.set(false, 'Wrong, please try again!');

console.log(question.get('question'));
console.log(question.size);


if(question.has(4)) {
    question.delete(4);
    console.log('Answer 4 is here')
}

question.clear();


question.forEach((value, key) => console.log(`This is ${key}, and it's set to ${value}`));


for (let [key, value] of question.entries()) {
    if (typeof(key) === 'number') {
        console.log(`Answer ${key}: ${value}`);
    }
}

const ans = parseInt(prompt('Write the correct answer'));
console.log(question.get(ans === question.get('correct')));

 

 

 

Classes

//ES5
var Person5 = function(name, yearOfBirth, job) {
    this.name = name;
    this.yearOfBirth = yearOfBirth;
    this.job = job;
}

Person5.prototype.calculateAge = function() {
    var age = new Date().getFullYear - this.yearOfBirth;
    console.log(age);
}

var john5 = new Person5('John', 1990, 'teacher');


//ES6
class Person6 {
    constructor (name, yearOfBirth, job) {
        this.name = name;
        this.yearOfBirth = yearOfBirth;
        this.job = job;
    }
    
    calculateAge() {
        var age = new Date().getFullYear - this.yearOfBirth;
        console.log(age);
    }
    
    static greeting() {
        console.log('Hey there!');
    }
}

const john6 = new Person6('John', 1990, 'teacher');

Person6.greeting();

 

 

 

Classes and Subclasses

//ES5
var Person5 = function(name, yearOfBirth, job) {
    this.name = name;
    this.yearOfBirth = yearOfBirth;
    this.job = job;
}

Person5.prototype.calculateAge = function() {
    var age = new Date().getFullYear() - this.yearOfBirth;
    console.log(age);
}

var Athlete5 = function(name, yearOfBirth, job, olymicGames, medals) {
    Person5.call(this, name, yearOfBirth, job);
    this.olymicGames = olymicGames;
    this.medals = medals;
}

Athlete5.prototype = Object.create(Person5.prototype);


Athlete5.prototype.wonMedal = function() {
    this.medals++;
    console.log(this.medals);
}


var johnAthlete5 = new Athlete5('John', 1990, 'swimmer', 3, 10);

johnAthlete5.calculateAge();
johnAthlete5.wonMedal();


//ES6
class Person6 {
    constructor (name, yearOfBirth, job) {
        this.name = name;
        this.yearOfBirth = yearOfBirth;
        this.job = job;
    }

    calculateAge() {
        var age = new Date().getFullYear() - this.yearOfBirth;
        console.log(age);
    }
}

class Athlete6 extends Person6 {
    constructor(name, yearOfBirth, job, olympicGames, medals) {
        super(name, yearOfBirth, job);
        this.olympicGames = olympicGames;
        this.medals = medals;
    }
    
    wonMedal() {
        this.medals++;
        console.log(this.medals);
    }
}

const johnAthlete6 = new Athlete6('John', 1990, 'swimmer', 3, 10);

johnAthlete6.wonMedal();
johnAthlete6.calculateAge();

 

 

 

Exercise

Suppose that you're working in a small town administration, and you're in charge of two town elements:
1. Parks
2. Streets
It's a very small town, so right now there are only 3 parks and 4 streets. All parks and streets have a name and a build year.
At an end-of-year meeting, your boss wants a final report with the following:
1. Tree density of each park in the town (forumla: number of trees/park area)
2. Average age of each town's park (forumla: sum of all ages/number of parks)
3. The name of the park that has more than 1000 trees
4. Total and average length of the town's streets
5. Size classification of all streets: tiny/small/normal/big/huge. If the size is unknown, the default is normal
All the report data should be printed to the console.
HINT: Use some of the ES6 features: classes, subclasses, template strings, default parameters, maps, arrow functions, destructuring, etc.

class Element {
    constructor(name, buildYear) {
        this.name = name;
        this.buildYear = buildYear;
    }
}


class Park extends Element {
    constructor(name, buildYear, area, numTrees) {
        super(name, buildYear);
        this.area = area; km2
        this.numTrees = numTrees;
    }
    
    treeDensity() {
        const density = this.numTrees / this.area;
        console.log(`${this.name} has a tree density of ${density} trees per square km.`);
    }
}


class Street extends Element {
    constructor(name, buildYear, length, size = 3) {
        super(name, buildYear);
        this.length = length;
        this.size = size;
    }
    
    classifyStreet () {
        const classification = new Map();
        classification.set(1, 'tiny');
        classification.set(2, 'small');
        classification.set(3, 'normal');
        classification.set(4, 'big');
        classification.set(5, 'huge');
        console.log(`${this.name}, build in ${this.buildYear}, is a ${classification.get(this.size)} street.`);
    }
}


const allParks = [new Park('Green Park', 1987, 0.2, 215),
                 new Park('National Park', 1894, 2.9, 3541),
                 new Park('Oak Park', 1953, 0.4, 949)];

const allStreets = [new Street('Ocean Avenue', 1999, 1.1, 4),
                   new Street('Evergreen Street', 2008, 2.7, 2),
                   new Street('4th Street', 2015, 0.8),
                   new Street('Sunset Boulevard', 1982, 2.5, 5)];


function calc(arr) {
    
    const sum = arr.reduce((prev, cur, index) => prev + cur, 0);
    
    return [sum, sum /arr.length];
    
}


function reportParks(p) {
    
    console.log('-----PARKS REPORT-----');
    
    // Density
    p.forEach(el => el.treeDensity());
    
    // Average age
    const ages = p.map(el => new Date().getFullYear() - el.buildYear);
    const [totalAge, avgAge] = calc(ages);
    console.log(`Our ${p.length} parks have an average of ${avgAge} years.`);
    
    // Which park has more than 1000 trees
    const i = p.map(el => el.numTrees).findIndex(el => el >= 1000);
    console.log(`${p[i].name} has more than 1000 trees.`);
    
}


function reportStreets(s) {
    
    console.log('-----STREETS REPORT-----');
    
    // Total and average length of the town's streets
    const [totalLength, avgLength] = calc(s.map(el => el.length));
    console.log(`Our ${s.length} streets have a total length of ${totalLength} km, with an average of ${avgLength} km.`);
    
    // CLassify sizes
    s.forEach(el => el.classifyStreet());
}

reportParks(allParks);
reportStreets(allStreets);
// LET and CONST ********************************************
// :변수와 상수


// ES5
var name5='Jane Smith';
var age5 = 23;
name5 = 'Jane Miller';
console.log(name5); //output// Jane Miller
// ES5에서는 변수와 상수의 구분이 x

// ES6
const name6 = 'Jane Smith';
let age6 = 23;
name6 ='Jane Miller';
console.log(name6); //output// VM84:3 Uncaught TypeError: Assignment to constant variable.

// const: constant variable: 상수
// let: in ES6 we don't use var anymore. let is replaced var.



/*
var와 let의 차이점

- var: function scope -> 선언되어진 함수 function 안에서라면 변수가 선언되어진 해당블록 밖에서도 접근가능

- let: blocked scope -> 변수는 변수가 선언된 블록 {}안에서만 접근 가능 (자바랑 비슷)
*/


// ES5
function driverLicence5(passedTest){
    if (passedTest){
        var firstName = 'John';
        var yearOfBirth = 1990;
    }
    console.log(firstName + ', born in ' + yearOfBirth + '. is now officially allowed to drive a car.'); 
}
driverLicence5(true);
// output // John, born in 1990. is now officially allowed to drive a car.


// ES6
function driverLicence6(passedTest){
    if (passedTest){
        let firstName = 'John';
        const yearOfBirth = 1990;
    }
    console.log(firstName + ', born in ' + yearOfBirth + '. is now officially allowed to drive a car.');
}
driverLicence6(true);
// output // VM143:23 Uncaught ReferenceError: firstName is not defined ->접근불가


// ES6 사용가능한 예시
function driverLicence6(passedTest){

    let firstName;
    const yearOfBirth = 1990; //const상수는 블록안에서 재정의 하는게 불가능(자바랑 마찬가지)

    if (passedTest){
        firstName = 'John';
    }
    console.log(firstName + ', born in ' + yearOfBirth + '. is now officially allowed to drive a car.');
}
driverLicence6(true);


// ex of let
let i = 23;
for(let i = 0; i < 5 ; i++){
    console.log(i);//이곳의 i와
}
console.log(i);//이곳의 i는 다르다.
//output
/*
0
1
2
3
4
23
*/

'javascript' 카테고리의 다른 글

JavaScript/ Functions!! 함수들  (0) 2020.04.14
JavaScript/ ES5 vs ES6  (0) 2020.03.09
JavaScript/ prototype & closure exercise  (0) 2020.03.09
JavaScript/ Bind, Call and Apply  (0) 2020.02.24
JavaScript/ Closure  (0) 2020.02.24
(function() {//give privacy

    
function Question(question, answers, correct){
    this.question = question;
    this.answers = answers;
    this.correct = correct;
}

Question.prototype.displayQ = function() {
    console.log(this.question);

    for(var i= 0; i<this.answers.length ; i++){
        console.log( i +":"+ this.answers[i]);
    }
}


Question.prototype.checkAnswer=
function(ans) {
    if(ans===this.correct){
        console.log('correct answer!');
    } else{
        console.log('you are wrong!!!');
    }
}

var q1 = new Question('Is JS coolest programing language in the world?', ['yes','no'], 0);

var q2 = new Question('What is the name of this course\'s teacher?', ['John','Micheal','Jonas'],2);

var q3 = new Question('What does best describr coding?', ['Boring', 'Hard', 'Fun','Tedious'],2);

var questions=[q1, q2, q3];

var n = Math.floor(Math.random()*questions.length);

questions[n].displayQ()

var answer = parseInt(prompt('Please select the correct answer.'));

questions[n].checkAnswer(answer);

})();

 

 

응용

(function() {//give privacy

    
    function Question(question, answers, correct){
        this.question = question;
        this.answers = answers;
        this.correct = correct;
    }
    
    Question.prototype.displayQ = function() {
        console.log(this.question);
    
        for(var i= 0; i<this.answers.length ; i++){
            console.log( i +":"+ this.answers[i]);
        }
    }
    

    Question.prototype.checkAnswer=
    function(ans, callback) {
        var sc;

        if(ans===this.correct){
            console.log('correct answer!');
            sc=callback(true);
        } else{
            console.log('you are wrong!!!');
            sc=callback(false);
        }
        this.displaySc(sc);

    }
    
    Question.prototype.displaySc = 
    function(score){
        console.log('your score is '+score);
        console.log('----------------------');
           
    }

    var q1 = new Question('Is JS coolest programing language in the world?', ['yes','no'], 0);
    
    var q2 = new Question('What is the name of this course\'s teacher?', ['John','Micheal','Jonas'],2);
    
    var q3 = new Question('What does best describr coding?', ['Boring', 'Hard', 'Fun','Tedious'],2);
    
    var questions=[q1, q2, q3];
   
    function score() {
        var sc = 0;
        return function(correct){
            if(correct){
                sc++;
            }
            return sc;
        }
    }

    var keepSc = score();

    function nextQ() {

        var n = Math.floor(Math.random()*questions.length);
    
        questions[n].displayQ()
    
        var answer = prompt('Please select the correct answer.');

        if(answer !== 'exit'){
            questions[n].checkAnswer(parseInt(answer), keepSc);
            nextQ();
        }        
    }
    nextQ();
})();
    
    
    

'javascript' 카테고리의 다른 글

JavaScript/ ES5 vs ES6  (0) 2020.03.09
JavaScript/ let , const & var  (0) 2020.03.09
JavaScript/ Bind, Call and Apply  (0) 2020.02.24
JavaScript/ Closure  (0) 2020.02.24
JavaScript/ Immediately Invoked Function Expressions [IIFE]  (0) 2020.02.24

bind()

- 메소드가 호출되면 새로운 함수를 생성

- 받게되는 첫 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공

 

apply() 

- 메서드는 주어진 this 값과 배열 (또는 유사 배열 객체) 로 제공되는 arguments 로 함수를 호출

 

call() 

- 메소드는 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출

:apply()와 call()은 거의 동일하지만, call()은 인수 목록을, 반면에 apply()는 인수 배열을 받는다.

 

 

var john = {
    name: 'John',
    age: 26,
    job:'teacher',
    presentation: function (style, timeOfDay){
        if (style === 'formal'){
            console.log('Good ' + timeOfDay + ', Ladies and gentlemen! I\'m '+ 
            this.name + ', I\'m a '+
            this.job+ ' and I\'m '+ 
            this.age + ' years old.');
        } else if (style === 'friendly'){
            console.log('Hey, nice ' + timeOfDay + '. I\'m '+ 
            this.name + ', I\'m a '+
            this.job+ ' and I\'m '+ 
            this.age + ' years old.');
        }
    }
};

var emily = {
    name: 'Emily',
    age: 35,
    job: 'designer'
};


john.presentation('formal','morning');
john.presentation.call(emily,'friendly', 'afternoon');
// using call method borrow john's presentation method
// method borrowing



//john.presentation.apply(emily, ['friendly', 'afternoon']);
// -> this is not worked, cuz presentation method doesn't expect to get an array as input.



//bind는 펑션을 빌려오는게 아니라 복사를 해서 따로 저장할 수 있다.
var johnFriendly = john.presentation.bind(john,'friendly');
johnFriendly('moring');
johnFriendly('night');
// get same printed result
// 같은 문구를 반복하지 않아도 되기 때문에 효율적

var emilyFormal = john.presentation.bind(emily,'formal');
emilyFormal('afternoon');

 

 

 

 

example

/ bind를 이용하여 나라별 성인 나이를 구하는 예제.

var years = [1990, 1965, 1937, 2005, 1998];

function arrayCalc(arr, fn){
    var arrRes = [];
    for (var i =0; i<arr.length; i++){
        arrRes.push(fn(arr[i]));
    }return arrRes;
}

function calculateAge(el){//el===birthDay
    return 2016-el;
}

function isFullAge(limit, el){//el===age
    return el >= limit;
}

var ages = arrayCalc(years, calculateAge);
var fullJapan = arrayCalc(ages, isFullAge.bind(this, 20));

console.log(ages);
console.log(fullJapan);

- 함수 안에서 값을 리턴하는 함수

an inner function has always access to the variables and parameters of its outer function,

even after the outer function has returned.

 

function retirement(retirementAge){
    var a = ' years left until retirement.';
    return function(yearOfBirth){
        var age = 2016 - yearOfBirth;
        console.log((retirementAge-age)+a);
    }
}

var retirementUS = retirement(66);
var retirementGermany = retirement(65);
var retirementEU = retirement(67);


retirementUS(1990);
retirement(66)(1990); 
// both give us same result
retirementGermany(1990);
retirementEU(1990);

 

 

 

 

challenge

/* rewirte this with closures
function interviewQuestion(job){
    if(job==='designer'){
        return function(name){
            console.log(name + ', can you please explain what UX design is?');
        }
    }
    else if(job==='teacher'){
        return function(name){
            console.log(name+', what subject do you teach?');
        }      
    }
    else{
        return function(name){
            console.log('hi,'+name+'! what do you do?');
        }
    }
}

var teacherQuestion = interviewQuestion('teacher');
var designerQuestion = interviewQuestion('designer');

teacherQuestion('John');
designerQuestion('Jane');
designerQuestion('Mark');

interviewQuestion('teacher')('Mark');
*/


function interviewQuestion(job) {
    return function (name) {
        if(job==='designer'){
            console.log(name + ', can you please explain what UX design is?');
        }
        else if(job==='teacher'){
            console.log(name+', what subject do you teach?');
        }
        else{ 
            console.log('hi,'+name+'! what do you do?'); 
        }
    }
} //-> 위의 함수와 달리 클로저를 이용하면 리턴문을 여러면 반복할 필요가 없다

interviewQuestion('teacher')('john');


 

Immediately Invoked Function Expressions [IIFE]


- JUST FOR DATA PRIVACY!!!

- 정의와 동시에 즉시 실행되는 함수

- 변수에 프라이버시를 주기 위해 함수를 생성하는건 비효율적임으로 IIFE형식을 이용한 1회성 함수를 만듬으로써 변수에 프라이버시를 부여

 

 

- 비효율적 예시

function game(){
    var score = Math.random() * 10;
    console.log(score >= 5);
}
game();

: if the only purpose of making function is hiding variables in a private function. we don't need to make named function like this.

-> so, use IIFE!!!

 

 

 

- IIFE

(function() {
    var score = Math.random() * 10;
    console.log(socore >= 5);
})();
// ()를 씀으로써 펑션으로써 바로 실행, 시스템을 속임
// 외부에서 score 변수에 바로 접근할 수 없으며 data privacy를 줌
console.log(socore)// printed undefined

//매개변수를 전달해줄수도 있음
(function(goodLuck) {//2.<-5를 전달받음
    var score = Math.random() * 10;
    console.log(socore >= 5 - goodLuck);// 3. 계산
})(5);//1.<-매개변수로 전달

: ()를 씀으로써 펑션으로써 바로 실행, 시스템을 속임
외부에서 score 변수에 바로 접근할 수 없으며 data privacy를 줌

'javascript' 카테고리의 다른 글

JavaScript/ Bind, Call and Apply  (0) 2020.02.24
JavaScript/ Closure  (0) 2020.02.24
JavaScript/ First-Class Functions  (0) 2020.02.24
JavaScript/ Primitives vs Objects  (0) 2020.02.24
JavaScript/ Function constructor  (0) 2020.02.24

- a Function is an instance of the object type.
- a Function behaves like any other object.
- we can store functions in a variable.
- we can pass a function as an argument to another function.
- we can return a function from a function. 
=> First-Class Functions

 

 

 

 

First-Class Functions: passing functions as arguments

var years = [1990, 1965, 1937, 2005, 1998];

function arrayCalc(arr, fn){ //array와 function을 매개변수로 받아온다.
    var arrRes =[]; // 새배열생성
    for(var i = 0 ; i < arr.length; i++ ){ //배열의 길이만큼 루프
        arrRes.push(fn(arr[i])); //새배열에 펑션의 결과를 넣어줌
    }
    return arrRes; // 값을 리턴
}

function calculateAge(el){ //생년
    return 2016-el;
}

function isFullAge(el){ //나이
    return el >= 18;
}

function maxHeartRate(el){ //나이
    if(el >=18 && el<=81){
    return Math.round(206.9 - (0.67 * el));// Math.round() 소수점 계산 출력
    }else{
        return -1;
    }
}

var ages = arrayCalc(years, calculateAge); // arrayCalc에 years 배열과 calculateAge 함수를 매개변수로 넣어준다.
var fullAges = arrayCalc(ages, isFullAge);
var heartRates = arrayCalc(ages, maxHeartRate);

console.log(ages);//[26, 51, 79, 11, 18]
console.log(fullAges);//[true, true, true, false, true]
console.log(heartRates);//[189, 173, 154, -1, 195]

=> this way is much readable and mergeable than create one big function and calculate every elements. (simple technique to make a clean code)

 

 

 

 

 

 

First-Class Functions: functions renturning functions

function interviewQuestion(job){
    if(job==='designer'){
        return function(name){
            console.log(name + ', can you please explain what UX design is?');
        }
    }
    else if(job==='teacher'){
        return function(name){
            console.log(name+', what subject do you teach?');
        }      
    }
    else{
        return function(name){
            console.log('hi,'+name+'! what do you do?');
        }
    }
}

var teacherQuestion = interviewQuestion('teacher');
var designerQuestion = interviewQuestion('designer');

teacherQuestion('John');
designerQuestion('Jane');
designerQuestion('Mark');

interviewQuestion('teacher')('Mark');

'javascript' 카테고리의 다른 글

JavaScript/ Closure  (0) 2020.02.24
JavaScript/ Immediately Invoked Function Expressions [IIFE]  (0) 2020.02.24
JavaScript/ Primitives vs Objects  (0) 2020.02.24
JavaScript/ Function constructor  (0) 2020.02.24
JavaScript/ The 'this' keyword  (0) 2020.02.24