From c0e9fb3250dbfae1d5b346a566b99869914582c2 Mon Sep 17 00:00:00 2001 From: chochi1st Date: Thu, 23 May 2019 16:28:45 +0800 Subject: [PATCH] Site updated: 2019-05-23 16:28:44 --- .../index.html" | 2 +- .../index.html" | 6 +- .../22/3 \345\257\271\350\261\241/index.html" | 6 +- .../22/4 \345\207\275\346\225\260/index.html" | 2 +- .../index.html" | 2 +- 2019/05/22/6 Array/index.html | 2 +- .../index.html" | 2 +- 2019/05/22/9 JavaScript Classes/index.html | 6 +- .../index.html" | 10 +-- "2019/05/22/Call\344\270\216Apply/index.html" | 6 +- 2019/05/22/hello-world/index.html | 2 +- .../index.html" | 2 +- .../22/\347\273\247\346\211\277/index.html" | 2 +- archives/2019/05/index.html | 14 +-- archives/2019/05/page/2/index.html | 2 +- archives/2019/index.html | 14 +-- archives/2019/page/2/index.html | 2 +- archives/index.html | 14 +-- archives/page/2/index.html | 2 +- .../index.html" | 14 +-- .../page/2/index.html" | 2 +- content.json | 2 +- index.html | 86 +++++++++---------- page/2/index.html | 2 +- showcase/showcase.html | 2 +- showcase/works/Ajax/ajax.html | 2 +- showcase/works/Ajax/readme.html | 2 +- showcase/works/BallGame/BallGame.html | 2 +- showcase/works/IamgeSlider/IamgeSlider.html | 2 +- showcase/works/flex/flex.html | 2 +- showcase/works/flex/readme.html | 2 +- tags/JS/index.html | 14 +-- tags/JS/page/2/index.html | 2 +- 33 files changed, 117 insertions(+), 117 deletions(-) diff --git "a/2019/05/22/1 \346\225\260\346\215\256\347\261\273\345\236\213/index.html" "b/2019/05/22/1 \346\225\260\346\215\256\347\261\273\345\236\213/index.html" index 5e93474..7be3017 100644 --- "a/2019/05/22/1 \346\225\260\346\215\256\347\261\273\345\236\213/index.html" +++ "b/2019/05/22/1 \346\225\260\346\215\256\347\261\273\345\236\213/index.html" @@ -30,7 +30,7 @@ diff --git "a/2019/05/22/2 \345\255\227\347\254\246\344\270\262/index.html" "b/2019/05/22/2 \345\255\227\347\254\246\344\270\262/index.html" index 13ec64a..1dae0c7 100644 --- "a/2019/05/22/2 \345\255\227\347\254\246\344\270\262/index.html" +++ "b/2019/05/22/2 \345\255\227\347\254\246\344\270\262/index.html" @@ -30,7 +30,7 @@ @@ -216,11 +216,11 @@

- +
- ECMA5 CALL APPLY 模拟 + ECMA5 面向对象编程
diff --git "a/2019/05/22/3 \345\257\271\350\261\241/index.html" "b/2019/05/22/3 \345\257\271\350\261\241/index.html" index 1a56367..1288f43 100644 --- "a/2019/05/22/3 \345\257\271\350\261\241/index.html" +++ "b/2019/05/22/3 \345\257\271\350\261\241/index.html" @@ -30,7 +30,7 @@ @@ -260,8 +260,8 @@

-
ECMA5 面向对象编程
+
+
ECMA6 类
diff --git "a/2019/05/22/4 \345\207\275\346\225\260/index.html" "b/2019/05/22/4 \345\207\275\346\225\260/index.html" index fd60dc6..cdcae60 100644 --- "a/2019/05/22/4 \345\207\275\346\225\260/index.html" +++ "b/2019/05/22/4 \345\207\275\346\225\260/index.html" @@ -30,7 +30,7 @@ diff --git "a/2019/05/22/5 \346\240\207\345\207\206\345\272\223/index.html" "b/2019/05/22/5 \346\240\207\345\207\206\345\272\223/index.html" index f87c6f9..c0ce2b3 100644 --- "a/2019/05/22/5 \346\240\207\345\207\206\345\272\223/index.html" +++ "b/2019/05/22/5 \346\240\207\345\207\206\345\272\223/index.html" @@ -30,7 +30,7 @@ diff --git a/2019/05/22/6 Array/index.html b/2019/05/22/6 Array/index.html index 7dd57a0..272886a 100644 --- a/2019/05/22/6 Array/index.html +++ b/2019/05/22/6 Array/index.html @@ -30,7 +30,7 @@ diff --git "a/2019/05/22/7 \345\214\205\350\243\205\345\257\271\350\261\241 wrapper/index.html" "b/2019/05/22/7 \345\214\205\350\243\205\345\257\271\350\261\241 wrapper/index.html" index 846fec2..667b91a 100644 --- "a/2019/05/22/7 \345\214\205\350\243\205\345\257\271\350\261\241 wrapper/index.html" +++ "b/2019/05/22/7 \345\214\205\350\243\205\345\257\271\350\261\241 wrapper/index.html" @@ -30,7 +30,7 @@ diff --git a/2019/05/22/9 JavaScript Classes/index.html b/2019/05/22/9 JavaScript Classes/index.html index 18f5183..d93efb8 100644 --- a/2019/05/22/9 JavaScript Classes/index.html +++ b/2019/05/22/9 JavaScript Classes/index.html @@ -30,7 +30,7 @@ @@ -236,11 +236,11 @@

- +
- ECMA5 面向对象编程 + ECMA5 对象
diff --git "a/2019/05/22/9 \351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/index.html" "b/2019/05/22/9 \351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/index.html" index 591db95..d44e49b 100644 --- "a/2019/05/22/9 \351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/index.html" +++ "b/2019/05/22/9 \351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/index.html" @@ -30,7 +30,7 @@ @@ -277,18 +277,18 @@

- +
- ECMA5 对象 + ECMA5 CALL APPLY 模拟
- -
ECMA6 类
+
+
ECMA5 字符串
diff --git "a/2019/05/22/Call\344\270\216Apply/index.html" "b/2019/05/22/Call\344\270\216Apply/index.html" index d8c005f..86d573a 100644 --- "a/2019/05/22/Call\344\270\216Apply/index.html" +++ "b/2019/05/22/Call\344\270\216Apply/index.html" @@ -30,7 +30,7 @@ @@ -244,8 +244,8 @@

-
ECMA5 字符串
+
+
ECMA5 面向对象编程
diff --git a/2019/05/22/hello-world/index.html b/2019/05/22/hello-world/index.html index f000091..04d44a2 100644 --- a/2019/05/22/hello-world/index.html +++ b/2019/05/22/hello-world/index.html @@ -29,7 +29,7 @@ diff --git "a/2019/05/22/\345\205\263\344\272\216 this \346\214\207\351\222\210/index.html" "b/2019/05/22/\345\205\263\344\272\216 this \346\214\207\351\222\210/index.html" index e505a27..fa3d8e1 100644 --- "a/2019/05/22/\345\205\263\344\272\216 this \346\214\207\351\222\210/index.html" +++ "b/2019/05/22/\345\205\263\344\272\216 this \346\214\207\351\222\210/index.html" @@ -30,7 +30,7 @@ diff --git "a/2019/05/22/\347\273\247\346\211\277/index.html" "b/2019/05/22/\347\273\247\346\211\277/index.html" index c8e3798..7e1d2b6 100644 --- "a/2019/05/22/\347\273\247\346\211\277/index.html" +++ "b/2019/05/22/\347\273\247\346\211\277/index.html" @@ -30,7 +30,7 @@ diff --git a/archives/2019/05/index.html b/archives/2019/05/index.html index a23af8a..1f5cff3 100644 --- a/archives/2019/05/index.html +++ b/archives/2019/05/index.html @@ -25,7 +25,7 @@ @@ -498,14 +498,14 @@

- ECMA5 面向对象编程 + ECMA6 类

@@ -547,14 +547,14 @@

- ECMA6 类 + ECMA5 CALL APPLY 模拟

@@ -596,14 +596,14 @@

- ECMA5 CALL APPLY 模拟 + ECMA5 面向对象编程

diff --git a/archives/2019/05/page/2/index.html b/archives/2019/05/page/2/index.html index 3cff00a..71fe415 100644 --- a/archives/2019/05/page/2/index.html +++ b/archives/2019/05/page/2/index.html @@ -25,7 +25,7 @@ diff --git a/archives/2019/index.html b/archives/2019/index.html index c5cc767..1ac72b7 100644 --- a/archives/2019/index.html +++ b/archives/2019/index.html @@ -25,7 +25,7 @@ @@ -498,14 +498,14 @@

- ECMA5 面向对象编程 + ECMA6 类

@@ -547,14 +547,14 @@

- ECMA6 类 + ECMA5 CALL APPLY 模拟

@@ -596,14 +596,14 @@

- ECMA5 CALL APPLY 模拟 + ECMA5 面向对象编程

diff --git a/archives/2019/page/2/index.html b/archives/2019/page/2/index.html index ef33b64..e6c38bc 100644 --- a/archives/2019/page/2/index.html +++ b/archives/2019/page/2/index.html @@ -25,7 +25,7 @@ diff --git a/archives/index.html b/archives/index.html index d64d9c0..d705ed4 100644 --- a/archives/index.html +++ b/archives/index.html @@ -25,7 +25,7 @@ @@ -498,14 +498,14 @@

- ECMA5 面向对象编程 + ECMA6 类

@@ -547,14 +547,14 @@

- ECMA6 类 + ECMA5 CALL APPLY 模拟

@@ -596,14 +596,14 @@

- ECMA5 CALL APPLY 模拟 + ECMA5 面向对象编程

diff --git a/archives/page/2/index.html b/archives/page/2/index.html index 9f83f92..db6a314 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -25,7 +25,7 @@ diff --git "a/categories/\350\257\255\350\250\200\345\237\272\347\241\200/index.html" "b/categories/\350\257\255\350\250\200\345\237\272\347\241\200/index.html" index 52764ba..7fc86ce 100644 --- "a/categories/\350\257\255\350\250\200\345\237\272\347\241\200/index.html" +++ "b/categories/\350\257\255\350\250\200\345\237\272\347\241\200/index.html" @@ -25,7 +25,7 @@ @@ -498,14 +498,14 @@

- ECMA5 面向对象编程 + ECMA6 类

@@ -547,14 +547,14 @@

- ECMA6 类 + ECMA5 CALL APPLY 模拟

@@ -596,14 +596,14 @@

- ECMA5 CALL APPLY 模拟 + ECMA5 面向对象编程

diff --git "a/categories/\350\257\255\350\250\200\345\237\272\347\241\200/page/2/index.html" "b/categories/\350\257\255\350\250\200\345\237\272\347\241\200/page/2/index.html" index 0c53c7c..7b6b9c5 100644 --- "a/categories/\350\257\255\350\250\200\345\237\272\347\241\200/page/2/index.html" +++ "b/categories/\350\257\255\350\250\200\345\237\272\347\241\200/page/2/index.html" @@ -25,7 +25,7 @@ diff --git a/content.json b/content.json index e28378a..2ec1f1c 100644 --- a/content.json +++ b/content.json @@ -1 +1 @@ -{"meta":{"title":"chochi's workshop","subtitle":null,"description":null,"author":"chochi","url":"http://yoursite.com","root":"/"},"pages":[{"title":"","date":"2019-05-23T03:49:37.681Z","updated":"2019-05-23T03:49:37.681Z","comments":true,"path":"showcase/style.css","permalink":"http://yoursite.com/showcase/style.css","excerpt":"","text":".chochi-container { width: 500px; height: 500px; } .chochi-container a{ color: black; text-decoration-line: none; } .chochi-container h2{ display: block; font-family: Arial, Helvetica, sans-serif; position: relative; margin: auto; margin-top: 120px; } #chochi-Works{ position: relative; top: 30px; margin: auto; display: flex; /* align-items: flex-start; align-items: flex-end; align-items: center; align-items: stretch; */ flex-direction: column; } #chochi-Works div{ border: 1px #cccccc solid; padding: 12px; border-radius: 8px; margin: 8px; height: 50px; box-sizing: border-box; /* width: 150px; */ transition: width .4s ease-in-out; } #chochi-Works div:hover{ width: 300px; border-radius: 10px; background-color: #cccccc; } .chochi-box-1{ flex: 1; width: 200px; } .chochi-box-2{ flex: 1; width: 180px; } .chochi-box-3{ flex: 1; width: 140px; } .chochi-box-4{ flex: 1; width: 220px; }"},{"title":"","date":"2019-05-23T03:48:58.628Z","updated":"2019-05-23T03:48:58.628Z","comments":true,"path":"showcase/showcase.html","permalink":"http://yoursite.com/showcase/showcase.html","excerpt":"","text":"chochi's workshop BallGame(正常) IamgeSlider FlexLayout JSONandAJAX(正常) 嵌入框架后项目就乱码了T T 寻找解决方法中"},{"title":"","date":"2019-05-23T03:01:14.707Z","updated":"2019-05-23T03:01:14.707Z","comments":true,"path":"showcase/works/Ajax/ajax.html","permalink":"http://yoursite.com/showcase/works/Ajax/ajax.html","excerpt":"","text":"Json and Ajax JSON and AJAX Fetch Info for 3 New Animals"},{"title":"","date":"2019-05-22T15:07:49.095Z","updated":"2019-05-22T11:39:16.649Z","comments":true,"path":"showcase/works/BallGame/BallGame.html","permalink":"http://yoursite.com/showcase/works/BallGame/BallGame.html","excerpt":"","text":"chochi's workshop #gamescreen{ border:1px solid red; } img{ display: none; width: 20px; height: 20px; } BallGame"},{"title":"","date":"2019-05-22T11:39:16.648Z","updated":"2019-05-22T11:39:16.648Z","comments":true,"path":"showcase/works/Ajax/ajax.js","permalink":"http://yoursite.com/showcase/works/Ajax/ajax.js","excerpt":"","text":"var btn = document.getElementById('btn'); var animinalContaniner = document.getElementById('animal-info'); var pageCounter = 1; btn.addEventListener('click',function(){ if( pageCounter > 3 ) return; var ourRequest = new XMLHttpRequest(); ourRequest.open('GET','https://learnwebcode.github.io/json-example/animals-'+ pageCounter +'.json'); ourRequest.onload = function(){ var ourData = JSON.parse(ourRequest.responseText); renderHTML(ourData); }; ourRequest.send(); animinalContaniner.style.display = 'block'; pageCounter++; if( pageCounter > 3 ){ // btn.style.display = 'none'; btn.style.transition = 'visibility 0.2s ease-in-out'; btn.style.visibility = 'hidden'; } }) function renderHTML(data){ var htmlString = \"\"; for(let item of data){ htmlString += '' + item.name + ' is a ' + item.species +'.'; } animinalContaniner.insertAdjacentHTML('beforeend',htmlString); // animinalContaniner.innerHTML = htmlString; }"},{"title":"","date":"2019-05-22T11:39:16.649Z","updated":"2019-05-22T11:39:16.649Z","comments":true,"path":"showcase/works/Ajax/readme.html","permalink":"http://yoursite.com/showcase/works/Ajax/readme.html","excerpt":"","text":""},{"title":"","date":"2019-05-23T03:01:22.616Z","updated":"2019-05-23T03:01:22.616Z","comments":true,"path":"showcase/works/Ajax/ajax.css","permalink":"http://yoursite.com/showcase/works/Ajax/ajax.css","excerpt":"","text":"#chochi-header{ display: -webkit-flex; display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center; } #chochi-header h1{ font-family: 'Times New Roman', Times, serif; margin: 20px; } #chochi-header button{ font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; background-color: cadetblue; border: none; color: aliceblue; border-radius: 10px; font-size: 16px; outline: none; } #animal-info{ display: none; border: cadetblue 4px dotted; padding: 3%; max-width: 45%; }"},{"title":"","date":"2019-05-22T11:39:16.657Z","updated":"2019-05-22T11:39:16.657Z","comments":true,"path":"showcase/works/IamgeSlider/IamgeSlider.html","permalink":"http://yoursite.com/showcase/works/IamgeSlider/IamgeSlider.html","excerpt":"","text":"Full screen image slider"},{"title":"","date":"2019-05-22T11:39:16.657Z","updated":"2019-05-22T11:39:16.657Z","comments":true,"path":"showcase/works/IamgeSlider/ImageSlider.js","permalink":"http://yoursite.com/showcase/works/IamgeSlider/ImageSlider.js","excerpt":"","text":"const slider = document.querySelector('.slider'); const imgs = document.querySelectorAll('.slider img'); // buttons const prevBtn = document.querySelector('#prevBtn'); const nextBtn = document.querySelector('#nextBtn'); // counter let counter = 1; let size = imgs[0].clientWidth; slider.style.transform = 'translateX(' + (-size * counter) + 'px)'; function clickNext(){ if(counter>=imgs.length-1) return;//防止快速点击 transitionend事件未监听到 slider.style.transition= 'transform 0.2s ease-in-out'; counter++; slider.style.transform = 'translateX(' + (-size * counter) + 'px)'; } function clickPrev(){ if(counter{ // console.log(counter); if(imgs[counter].id ==='lastClone'){ slider.style.transition = 'none';//直接替换不要渐进 counter = imgs.length - 2; slider.style.transform = 'translateX(' + (-size * counter) + 'px)'; } if(imgs[counter].id ==='firstClone'){ slider.style.transition = 'none'; counter = imgs.length - counter; // console.log(imgs.length,counter); slider.style.transform = 'translateX(' + (-size * counter) + 'px)'; } });"},{"title":"","date":"2019-05-22T11:39:16.674Z","updated":"2019-05-22T11:39:16.674Z","comments":true,"path":"showcase/works/IamgeSlider/style.css","permalink":"http://yoursite.com/showcase/works/IamgeSlider/style.css","excerpt":"","text":"*{ padding: 0px; margin: 0px; box-sizing: border-box; } .container{ width: 628px; margin: auto; overflow: hidden; position: relative; } .slider{ display: flex; width: 100%; height: 100%; } .btn{ position: absolute; width: 10%; height:7%; background: transparent; border: 0px; outline: none; } #prevBtn{ top:50%; left: 5%; } #nextBtn{ top:50%; right: 5%; }"},{"title":"","date":"2019-05-23T03:04:59.199Z","updated":"2019-05-23T03:04:59.199Z","comments":true,"path":"showcase/works/flex/flex.html","permalink":"http://yoursite.com/showcase/works/flex/flex.html","excerpt":"","text":"flex layout FLEX LAYOUT"},{"title":"","date":"2019-05-22T11:39:16.675Z","updated":"2019-05-22T11:39:16.675Z","comments":true,"path":"showcase/works/flex/readme.html","permalink":"http://yoursite.com/showcase/works/flex/readme.html","excerpt":"","text":"flex layout"},{"title":"","date":"2019-05-23T03:04:56.030Z","updated":"2019-05-23T03:04:56.030Z","comments":true,"path":"showcase/works/flex/flex.css","permalink":"http://yoursite.com/showcase/works/flex/flex.css","excerpt":"","text":"#chochi-html,#chochi-body{ margin: 0; padding: 0; height: 100%; width: 100%; background-color: darkslategrey; } .chochi-header { height: 100px; text-align: center; position: relative; } .chochi-header h1 { margin-top: 50px; color: aliceblue; font-family: 'Times New Roman', Times, serif; position: absolute; } #chochi-parent { padding: 10px; margin: auto; height: 100%; width: 100%; display: flex; flex-flow: row wrap; align-items: flex-start; justify-content: center; align-content: flex-start; } #chochi-parent div { margin: 10px; padding: 10px; height: 100px; width: 100px; background-color: aliceblue; border-radius: 10%; box-sizing: border-box; box-shadow: 2px 2px 2px darkgray; } #chochi-parent span{ width: 20px; height: 20px; background-color: black; border-radius: 50%; } #chochi-parent .num1 { display: flex; flex-direction: row; align-items: center; justify-content: center; } #chochi-parent .num2 { display: flex; flex-direction: row; justify-content: space-around; align-items: center; } #chochi-parent .num3 { display: flex; flex-direction: row; justify-content: space-around; } #chochi-parent .num3 .item:nth-child(2){ align-self: center; } #chochi-parent .num3 .item:last-child{ align-self: flex-end; } #chochi-parent .num4 div { margin: 0; padding: 0; width: 100px; height: 100px; box-shadow: none; display: flex; justify-content: space-around; align-items: center; } #chochi-parent .num4 { margin-top: 10px; padding: 0; display: flex; flex-direction: column; }"},{"title":"","date":"2019-05-22T11:39:16.655Z","updated":"2019-05-22T11:39:16.655Z","comments":true,"path":"showcase/works/BallGame/src/index.js","permalink":"http://yoursite.com/showcase/works/BallGame/src/index.js","excerpt":"","text":"import {Game} from './game.mjs'; const canvas = document.querySelector('#gamescreen'); const ctx = canvas.getContext('2d'); const GAME_WIDTH = 800; const GAME_HEIGHT = 600; ctx.clearRect(0,0,800,600); let game = new Game(GAME_WIDTH,GAME_HEIGHT); // game.start(); let lastTime = 0; //let imgBall = document.querySelector('#ball'); function gameLoop(timeStamp){ let deltaTime = timeStamp - lastTime; lastTime = timeStamp; ctx.clearRect(0,0,GAME_WIDTH,GAME_HEIGHT); game.update(deltaTime); game.draw(ctx); requestAnimationFrame(gameLoop); } gameLoop();"}],"posts":[{"title":"ECMA5 继承","slug":"继承","date":"2019-05-22T14:38:04.278Z","updated":"2019-05-22T14:48:03.891Z","comments":true,"path":"2019/05/22/继承/","link":"","permalink":"http://yoursite.com/2019/05/22/继承/","excerpt":"2 继承ECMAScript 只支持实现继承,不支持接口继承。 继承方法类型: 原型链继承 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承2.1 原型链继承 基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法,实现的本质是重写原型对象,代之一个新类型的实例 原型对象可以算是是一个‘实例’,有用constructor指针,指向其构造函数 构造函数有prototype指针指向原型对象 实例有proto指针执行其原型对象 Father().prototype —> Father.prototype [原型对象] Father.prototype.constructor –> Father() [构造函数] InstanceOfFather. proto –> Father.prototype 问题: 引用类型的原型属性会被所有实例共享 注意代码块中原型链继承的tips 在创建子类的实例时,不能像超类中的构造函数传递参数","text":"2 继承ECMAScript 只支持实现继承,不支持接口继承。 继承方法类型: 原型链继承 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承2.1 原型链继承 基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法,实现的本质是重写原型对象,代之一个新类型的实例 原型对象可以算是是一个‘实例’,有用constructor指针,指向其构造函数 构造函数有prototype指针指向原型对象 实例有proto指针执行其原型对象 Father().prototype —> Father.prototype [原型对象] Father.prototype.constructor –> Father() [构造函数] InstanceOfFather. proto –> Father.prototype 问题: 引用类型的原型属性会被所有实例共享 注意代码块中原型链继承的tips 在创建子类的实例时,不能像超类中的构造函数传递参数 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 //构造函数 function Father(){ this.name = 'Big Dady'; this.title = 'father'; } //实例方法 Father.prototype.sayName = function (){ console.log(this.name); } //构造函数 function Son(){ this.title = 'son'; this.age = 19; this.objInSonInstance = { sister: 'chesnut' } }//-------------------- tips 原型链继承 存疑中 ----------------------------------- // Son 继承 Father的一个实例 // Father() 中所有属性被衍生类共享 // 只不过普通属性被更改了binding,在实例中拥有了该属性,不会再像原型链搜素 // 引用属性除非是直接更改binding,否则是所有实例都共享了这个属性 Son.prototype = new Father();//------------------------------------------------------------------------------- Son.prototype.objInSon={ brother: 'flag' } //Son的实例方法: !先继承再添加子类的实例方法,不然会被覆盖! Son.prototype.sayTitle = function(){ console.log(this.title); } //在类上的静态方法 Son.staticMethod = function(){ console.log('static!!!'); } //创建Son类的一个实例 instance let instance = new Son(); let instance2 = new Son(); /** instance 的属性搜索链: instance properties: age,title(son),objInSonInstance 以下为原型链层,所有引用的属性会被共享(函数也算对象,对象是引用类型,所有实例共享引用类型、函数) __proto__ properties: name,title(father),sayTitle,objInSon __proto__.__proto__ properties: sayName **/ console.log(instance.hasOwnProperty('title')); //true console.log(instance.__proto__.hasOwnProperty('title')); //true console.log(instance.__proto__.__proto__.hasOwnProperty('sayName')); //true console.log(instance.title, instance.__proto__.title); //son,father console.log(Son.hasOwnProperty('staticMethod')); //true // 实例引用属性,互不影响 instance.objInSonInstance.addInInstance = 'instance add'; console.log(instance.objInSonInstance,instance2.objInSonInstance); //原型上引用属性被共享,instance2.objInSon 被更改 instance.objInSon.addInPrototype = 'prototype add'; console.log(instance.objInSon,instance2.objInSon); 2.2 借用构造函数 借用构造函数并无构成真正意义上的继承 可以传参,引用类型不会被共享,但无法达到函数复用的目的。 1234567891011121314151617181920//借用构造函数 function Super(){ this.refType = [1,2,3]; this.basicType = 'Super basic type';}//Sub不可用该方法Super.prototype.printData = function (property){ console.log(this[property]);}// Sub的原型对象还是objectfunction Sub(){ Super.call(this);}let in1 = new Sub();let in2 = new Sub();console.log(in1.__proto__,Sub.prototype);// object objectin1.printData('refType');//error: not a functionin1.refType.push(1);console.log(in2.refType);//1,2,3 2.3 原型式继承 一个对象作为另外一个对象的继承,原型对象的所有属性被共享,故达到函数复用目的 1234567891011121314151617// 一个对象实例,作为模板let Person = { name:'chochi', // 子类赋值重写,所有看起来不被共享 habbits:['reading','speaking'], print: function(){ console.log(this.name,this.habbits); }}//浅复制let chochi = Object.create(Person);let chesnut = Object.create(Person);chochi.habbits.push('eating');chesnut.print();//reading speaking eatingconsole.log(chesnut.print===chochi.print);// true:函数复用 2.4 组合继承 概念: 使用原型链实现对需要共享的属性和方法的继承 借用构造函数完成实例属性的继承 实例属性屏蔽原型属性 可被 instanceof , isPrototypeOf 识别 融合优点,最常用 问题: 调用两次构造函数,一次是创建子类原型,一次是子类构造函数内部。—》 解决:寄生组合式继承12345678910111213141516171819202122232425 function Father(_title){ this.refTitle ={ title: _title }; } Father.prototype.printProperty = function (){ console.log(this.refTitle); } function Son(_title,_age){ // 借用构造函数:创建实例属性 Father.call(this,_title); this.age = _age; /* 实例属性 property: age, refTitle{title} */ } // 重写原型:共享方法 // 原型上也有了 refTitle 属性,虽然被实例属性屏蔽了,等于一个属性存在了两次 Son.prototype = new Father();//------------ tips --------------------------// 将指针值回来除了逻辑更加清晰其他的改变? Son.prototype.constructor = Son;//-------------------------------------------- 2.5 寄生组合继承 可以直接简化成下面 将组合继承的原型重写那一步改成以下: 如此就不用call两次构造函数,属性也不会被重复 1Son.prototype = Father.prototype;","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 包装对象","slug":"7 包装对象 wrapper","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:49:12.973Z","comments":true,"path":"2019/05/22/7 包装对象 wrapper/","link":"","permalink":"http://yoursite.com/2019/05/22/7 包装对象 wrapper/","excerpt":"1 定义 数值、字符串、布尔值这三种原型类型的值,在一听条件下也会自动转化为对象,也就是原始类型的包装对象。 Number String Boolean 包装对象的目的,是得对象模型覆盖js所优质,正门语言都有一个通用的数据模型,其次是得原始类型的值也有可以调动自己的方法。 原始类型的值会自动当做包装对象调用,即调用包装对象的属性和方法。JS引擎糊自动将原始类型的值转换为包装对象实例,并在使用后立即销毁。 自动转换生成的包装对象是只读的,无法修改。 1234567891011var str = 'abc';str.length; // 3// 等同于var strObj = new String(str);/* String{ 0:\"1\",1:\"b\",2;\"c\",length:3[[PrimitiveValue]]:\"abc\" } strObj.length;//3*/","text":"1 定义 数值、字符串、布尔值这三种原型类型的值,在一听条件下也会自动转化为对象,也就是原始类型的包装对象。 Number String Boolean 包装对象的目的,是得对象模型覆盖js所优质,正门语言都有一个通用的数据模型,其次是得原始类型的值也有可以调动自己的方法。 原始类型的值会自动当做包装对象调用,即调用包装对象的属性和方法。JS引擎糊自动将原始类型的值转换为包装对象实例,并在使用后立即销毁。 自动转换生成的包装对象是只读的,无法修改。 1234567891011var str = 'abc';str.length; // 3// 等同于var strObj = new String(str);/* String{ 0:\"1\",1:\"b\",2;\"c\",length:3[[PrimitiveValue]]:\"abc\" } strObj.length;//3*/ 2 Boolean2.1 if ()12if ( new Boolean(flase)) // true 逻辑运算,所有对象为trueif ( new Boolean(false).valueOf())//false 返回实例原始值 3 正则表达式3.1 建立 字面量方法在引擎编译代码的时候建立正则表达式,所以较为高效12var regex = /xyz/; // 编译时建立var regex = new RegExp('xyz'); // 运行时建立 3.2 实例属性1234567//以下属性只读 // 返回布尔值 是否有设置当前修饰 regex.ignoreCase; regex.global; regex.multiline; // 返回字符串,包含已经设置的所有修饰符,按字母排序 regex.flags; 3.3 实例方法 RegExp.prototype.test() 从 lastIndex 位置向后匹配,找到当前模式能匹配的参数字符串则返回 true 带有g修饰符,每次test()都从上一次结束的位置开始向后匹配1234567var regex = /r/g;var str = '_x_x';regex.lastIndex ; // 0regex.test(s); //trueregex.lastIndex; // 2 _regex.lastIdex = 4; // 可指定搜索位置,只对同一个正则表达式有效regex.test(s); //false RegExp.prototype.exec() 返回匹配结果(数组) 包含 input index 属性 12345678910var r = /a(b+)a/;var match = r.exec('_abbbbba_aba_');console.log(match);/* Array(2) [\"abbbbba\", \"bbbbb\"] index:1 整个匹配模式成功的开始位置 input:\"_abbbbba_aba_\" 整个字符串 length:2 第二个成员是组匹配结果*/ 3.4 字符串的实例方法 match() 返回匹配结果 若带 g 修饰,则一次性返回所有结果 正则表达式的 lastIndex 属性不造成影响123var s = 'abba_aba_abaa';var r = /a(b+)a/g;var results = s.match(r);//Array(3) [\"abba\", \"aba\", \"aba\"] search() 返回第一个满足条件的匹配结果在整个字符串中的位置 replace(search,replacement) 若带 g 修饰符,则替换所有匹配成功的项","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 函数","slug":"4 函数","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:53:07.745Z","comments":true,"path":"2019/05/22/4 函数/","link":"","permalink":"http://yoursite.com/2019/05/22/4 函数/","excerpt":"1 概述1.1 重复声明 函数的声明会提升到函数定义时所在的作用域的头部。故同名函数会被后来的函数替代。 12345678function f(){ console.log('one');}f(); //twofunction f(){ console.log('two');}f(); //two","text":"1 概述1.1 重复声明 函数的声明会提升到函数定义时所在的作用域的头部。故同名函数会被后来的函数替代。 12345678function f(){ console.log('one');}f(); //twofunction f(){ console.log('two');}f(); //two 1.2 函数名的提升 函数声明会提升 12f(); // its okfunction f(){} 函数表达式不提升 使用 var ,var变量提升 ,可识别到变量被声明,但没有定义。 使用 let ,变量未定义。123456789 f(); // f is not a function var f = function(){};//等同于 var f; f(); f = function(){};//使用 let f(); // f is not defined let f = function(){}; 2 函数的属性和方法2.1 name 返回函数的名字2.2 length 返回函数预期传入参数的个数2.3 toString() 返回一个字符串,内容是函数的源码 123456 // 可实现多行字符串 function f(){/* 这是一个 多行注释 */}f.toString() 3 函数作用域3.1 定义 es5 中:全局和函数作用域。 对于 var 命令, 局部变量只能在函数内部声明,其他块区中声明一律为全局变量。3.2 函数内部的变量提升 var,函数声明都会提升到函数体头部3.3 函数本身的作用域 函数本身的作用域就是其声明时所在的作用域,与其运行所在的作用域无关。123456789101112var a = false ;var inside = function(){ console.log(a);}function outside(){ var a = true; inside();}outside(); // false 123456789101112var a = false ;function outside(){ var a = true; var inside = function(){ console.log(a); } inside();}outside(); // true 4 参数 传递方式 passes by value 允许有不定数目的参数4.1 arguments 对象 正常模式下, arguments 允许运行时修改 该对象的 length 属性,可以判断函数调用时到底带几个参数。 callee 属性,指向对应的原函数。 5 闭包 读取函数内部的变量 闭包可以使得诞生环节一直存在,内部变量记住上一次调用时的运算结果 封装对象的私有属性和私有方法 外层函数每次运行,都会生成一个新闭包。每一个闭包变量独立,不共享。 闭包的内存消耗很大,会造成网页的性能问题。 12345678function createIncrementor(start){ return function(){ return start++; }}var ins = createIncrementor(0);ins(); // 0ins(); // 1 6 立即调用的函数表达式 IIFE function 关键字出现在行首一律解释为语句。让引擎理解为表达式,普通的方法是将函数放在括号里。 1(function(){/* code */})(); 不必为函数命名,避免污染全局变量。 形成单独的作用域,封装外部无法读取的私有变量。7 eval 使用别名调用一律为全局作用域。","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 this指针","slug":"关于 this 指针","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:54:45.463Z","comments":true,"path":"2019/05/22/关于 this 指针/","link":"","permalink":"http://yoursite.com/2019/05/22/关于 this 指针/","excerpt":"1 概念 this 对象时运行时基于函数的执行环节绑定的,在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。 匿名函数的执行环节具有全局性,因此this指针对象通常指向window 12345678910let obj = { fun : function(){ console.log(this);//obj return function(){ console.log(this);//window 匿名函数有全局性 }; }};","text":"1 概念 this 对象时运行时基于函数的执行环节绑定的,在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。 匿名函数的执行环节具有全局性,因此this指针对象通常指向window 12345678910let obj = { fun : function(){ console.log(this);//obj return function(){ console.log(this);//window 匿名函数有全局性 }; }}; 每个函数在被调用的时候都被自动取得两个特殊的变量:this & arguments 。 内部函数在搜索这两个变量的时候,只会搜索到其活动对象位置,因此不可能直接访问外部函数中的这两个变量。 可以将外部作用域中的this对象保存在一个闭包能访问的变量里1234567891011let obj = { fun : function(){ console.log(this);//obj let that = this; return function(){ console.log(that);//obj 函数闭包把that包括进来 }; } };","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 标准库","slug":"5 标准库","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:53:23.277Z","comments":true,"path":"2019/05/22/5 标准库/","link":"","permalink":"http://yoursite.com/2019/05/22/5 标准库/","excerpt":"1 判断某个变量是否为函数123function isObject(value){ return value === Object(value); } 2 对象的键名","text":"1 判断某个变量是否为函数123function isObject(value){ return value === Object(value); } 2 对象的键名 12Object.keys // 返回对象本身(不包括继承)的可枚举属性Object.getOwnPropertyNames // 返回对象本身的所有属性(不包括继承) 3 判断数据类型 toString 返回对象的类型字符串,因此可以用来判断一个值的类型,返回的第一个值表示该值的构造函数。 但由于实力对象可能会自定义该方法,所有调用原型上的方法。1Object.prototype.toString.call(value) 4 属性描述对象 value writable 是否可写 enumerable 是否可枚举 值为false时 for..in Object.keys 会跳过该属性 configurable 空值属性描写对象的可写性 get set 1Object.getOwnPropertyDescriptor(obj,PropertyName) // 活动对象本身属性描述对象 12345678910// 使用属性描述对象定义或修改一个属性var obj = Object.defineProperty({},'p',{ value:123, writable:false, enumerable:true, configurable:false});obj.p=456;obj.p; //123 若一个属性的enumerable为false,以下操作不会取到该属性 for … in Object.keys 5 对象的拷贝1234567891011var extend = function (to,from){ for( let property in from){ if(!from.hasOwnProperty(property))continue; Object.defineProperty( to, property, Object.getOwnPropertyDescriptor(from,property) // 读不到继承属性的属性描述对象 ); } return to;} 6 控制对象的状态 冻结对象 1234 // 弱到强Object.preventExtensions(obj);// 无法添加新属性Object.seal(obj);// 无法添加or删除属性Object.freeze(obj);//无法添加or删除属性,无法改变属性的值,该对象实际上变成了常量 以上方法,可以改变原型对象,来为对象增加属性","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 数组","slug":"6 Array","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:53:38.911Z","comments":true,"path":"2019/05/22/6 Array/","link":"","permalink":"http://yoursite.com/2019/05/22/6 Array/","excerpt":"1 静态方法1.1 判断是否为数组 使用Array的静态方法 1Array.isArray( array ) 使用原型toString方法,返回的字符串第二个词表示构造函数 1Object.prototype.toString.call( array ) // [object array]","text":"1 静态方法1.1 判断是否为数组 使用Array的静态方法 1Array.isArray( array ) 使用原型toString方法,返回的字符串第二个词表示构造函数 1Object.prototype.toString.call( array ) // [object array] instanceof (不太靠谱) 12[] instanceof Object // true[] instanceof Array // true 2 实例方法 valueOf() 返回数组本身 toString() 返回数组字符串形式 push() 在数组的末端添加一个或多个元素 返回数组长度 pop() 删除数组最后一个元素 返回被删除的元素 shift() 删除数组第一个元素 返回被删除的元素 unshitf() 在数组第一个位置添加元素 返回数组长度 实例方法 ————| 操作 | 参数 | 返回 | 是否改变原数组 | 其他 || :—– | :—- | :—- | :— | :—- | :—- || valueOf()||| 返回数组本身 | 否 | || toString()|| | 返回数组字符串形式 | 否 | || push() | 在数组的末端添加一个或多个元素 | 添加的元素 | 返回数组长度 |是||| pop() | 删除数组最后一个元素 | 无 | 返回被删除的元素|是||| shift() | 删除数组第一个元素 | 无 | 返回被删除的元素|是||| unshitf() | 在数组第一个位置添加元素 | 添加的元素 | 返回数组长度|是||| join()|以参数为分隔符,将数组成员链接为一个字符串| 分隔符|返回字符串|否|undefined or null or hole 转为空字符串||cantact()|链接多个数组|数组|返回一个新数组|否|数组浅拷贝(对象涉及引用问题)||recerse()|反转数组|无|改变后的数组|是|||slice()| 提取数组的一部分|start,end(允许负数)|返回新数组|否|参数不合理则返回空数组||splice()|删除原数组的一部分,可在删除的位置添加新成员|start,cnt,addItem1,add..|返回被删除的元素|是|start接受负数||sort()|对原数组进行排序,默认字典序|自定义比较函数||是|数值也会被默认转为字符串||map()|成员依次执行函数,返回执行结果组成的数组|(fun(item,index,arr),obj)函数后两项可省略,obj用来绑定this|返回结果组成的新数组|否|只跳过hole,undefined & null 不跳过||forEach()|依次执行参数函数,不返回|同上|无|否|无法中断执行,同上||filter()|满足条件的成员组成新数组返回|同上|满足条件的成员组成新数组返回|否|||every()|所有成员返回true,则结果返回true|同上|布尔值|否|||reduce()|依次处理每个成员,最终累计为一个值|fun(sum,curItem,index,arr)前两个必须|sum|否|||indexf()|参数在数组中第一次出现的位置|搜索的元素|下标 or -1 | 否|内部搜索使用 ===|","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 对象","slug":"3 对象","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:52:44.830Z","comments":true,"path":"2019/05/22/3 对象/","link":"","permalink":"http://yoursite.com/2019/05/22/3 对象/","excerpt":"1 键名 对象的所有键名都是字符串,若键名不符合标识符的条件,则必须加上引号。 如果使用方运算符,键名必须放在引号里,否则会被当做变量处理。 数字键可以不加引号,会自动转成字符串。123456let obj = { flag: true };obj[flag] // undefinedobj.flag // trueobj.['flag'] // trueflag ='flag';obj[flag] // ture","text":"1 键名 对象的所有键名都是字符串,若键名不符合标识符的条件,则必须加上引号。 如果使用方运算符,键名必须放在引号里,否则会被当做变量处理。 数字键可以不加引号,会自动转成字符串。123456let obj = { flag: true };obj[flag] // undefinedobj.flag // trueobj.['flag'] // trueflag ='flag';obj[flag] // ture 对象的每一个键名又称为属性 property,它的键值可以是任何数据类型。2 属性2.1 属性的查看 查看对象本身的所有可枚举属性1Object.keys 2.2 属性的删除 只能删除对象本身的属性,无法删除继承得来的属性。 使用 delete 删除完对象的属性后,Object.keys 方法的返回值也不再包括该属性。 只有一种情况 delete 命令返回 false ,该属性存在但不可删除 configurable:false2.3 属性是否存在 ‘PropertyName’ in obj :是否存在该属性,包括继承而来 hasOwnProperty(‘PropertyName’) :对象本身是拥有该属性2.4 属性的遍历 遍历所有可枚举的属性,包括继承而来的 1for...in 遍历所有可枚举的本身属性(enumerable) 123456// 遍历对象本身属性for( let key in obj){ if( obj.hasOwnProperty(key)){ /* do some operations */ }} 2.5 with 语句 with 语句内只能创建全局变量。 with的绑定对象不明确所以弄临时变量代替with123with( obj ){ /** do operations **/} 遍历总结 for.. in 包括继承而来的可枚举属性 Object.keys 不包括继承的的可枚举属性 Object.getOwnPropertyNames 本身的所有属性","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 面向对象编程","slug":"9 面向对象编程","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:48:49.890Z","comments":true,"path":"2019/05/22/9 面向对象编程/","link":"","permalink":"http://yoursite.com/2019/05/22/9 面向对象编程/","excerpt":"1 实例对象与new 命令1.1 构造函数 函数体内部使用了 this 关键字,代表了所要生成的对象实例。 生成对象的时候,必须使用 new 命令 函数名首字母大写,以示区别。 1.2 new 命令 执行构造函数,返回一个对象实例。 1.2.1 new 原理1234graph TB A[1.创建一个空对象作为将要返回的对象实例]--> B[2.将这个空对象的原型指向构造函数的prototype属性] B-->C[3.将空对象赋值给函数内部的this关键字] C-->D[4.开始执行构造函数内部的代码]","text":"1 实例对象与new 命令1.1 构造函数 函数体内部使用了 this 关键字,代表了所要生成的对象实例。 生成对象的时候,必须使用 new 命令 函数名首字母大写,以示区别。 1.2 new 命令 执行构造函数,返回一个对象实例。 1.2.1 new 原理1234graph TB A[1.创建一个空对象作为将要返回的对象实例]--> B[2.将这个空对象的原型指向构造函数的prototype属性] B-->C[3.将空对象赋值给函数内部的this关键字] C-->D[4.开始执行构造函数内部的代码] 12345678910111213function _new(constructor,params){ var args = [].slice.call(arguments); var constructor = args.shift(); // 创建一个空对象,继承构造函数的prototype属性 var context = Object.create(constructor.prototype); //执行构造函数 var result = constructor.apply(context, args); //返回结构是对象就直接返回,否则返回一个空对象 return (typeof result === 'object' && result != null) ? result : context;} 1.2.2 new.target 如果当前函数是new命令调用的,new.target指向当前函数,否则为 undefined 使用该属性判断函数调用的时候是否使用了new命令。 2 this 关键字 this 就是属性或方法“当前”所在的对象 this 的指向是可变的 2.1 this 实质1var obj = { foo : 5 }; 1.引擎会在内存中生成一个对象{ foo : 5 } 2.把这个对象的内存地址赋值给变量obj 3.若属性的值是一个函数,引擎会将函数单独保存在内存中,如何再讲函数的地址赋值给foo属性的value属性。 this 的目的在函数体内部,只带函数当前的运行环境。 123456{ foo:{ [[value]]: reference of function .... }} 2.2 this 的使用场合全局环境 只有在全局环节下运行,this就是指顶层对象 window 构造函数 在构造函数中的 this ,指的是实例对象 对象的方法 如果对象的方法里面包含this, this的执行就是方法运行时所在的对象,该方法赋值给另一个对象,就会改变this指向。 若将对象内部或者嵌套对象内部的方法赋值给一个变量,this会指向全局变量。1234567891011121314var a = { b:{ method : function(){ console.log(this); } }, method:function(){ console.log(this); }};var textb = a.b.method;textb(); // windowvar texta = a;a.method(); // object a 在函数中定义的匿名函数的this指向全局对象2.3 绑定 this 使用 call,apply,bind,切换/固定this指向。 bind 函数每运行一次,就返回一个新函数,故监听和回调事件的时候需注意 12345678910111213var counter = { cnt : 0, increament:function(){ 'use strict'; this.cnt++; }}function callIt(callback){ callback();}callIt( counter.increament.bind(counter) ); // 绑定对象,如果直接传函数的referce则this变为windowcounter.cnt; //1 在非 use strict 的情况下可改变为window,在严格模式下报错undefined 1234567891011121314var cnt = 100;var counter = { cnt : 0, increament:function(){ this.cnt++; }}function callIt(callback){ callback();}callIt( counter.increament);// this 指向变为windowconsole.log(counter.cnt,cnt); // 0 101 2.3.1 bind留与call方法使用1234var push = Function.prototype.call.bind(Array.prototype.push);var a = [1,2,3];push(a,4);a; // [1,2,3,4] 3 ES5 对象的继承 js的继承通过“原型对象” prototype 实现。 3.1 原型对象概述 缺点:实例之间无法共享属性 123456789function Cat(_name){ this.name = _name; // 每个实例都会创建一次这个方法 ins1.meow !== ins2.meow // 使用prototype属性解决 this.meow = function(){ console.log('miao!~'); }} 3.2 prototype 属性 定义所有实例对象共享的属性和方法,而实例可以视作从原型对象衍生处理的子对象。 3.3 原型链 prototype chain 所有对象都继承了Object.proto的属性。123// 原型链尽头是 null Object.getPrototypeOf(Object.prototype); // nullObject.prototype.__proto__; // null 等价写法 3.4 constructor 属性 prototype 对象有constructor属性,默认指向prototype对象所在的构造函数。 可以被实例对象继承。使实例对象能被知晓是被哪个构造函数产生。 可以使用 constructor 属性 从一个实例对象新建另一个实例。 constructor属性表示原型对象与构造函数直接的关联关系,如果修改了原型对象,需要同时修改constructor属性。 跳 对象的相关方法","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA6 类","slug":"9 JavaScript Classes","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:54:09.225Z","comments":true,"path":"2019/05/22/9 JavaScript Classes/","link":"","permalink":"http://yoursite.com/2019/05/22/9 JavaScript Classes/","excerpt":"Classes1 Class-Like structures in ecma51234567891011121314// propertyfunction PersonType(name){ this.name = name;}// methods: be assigned to the prototype // all instances of the object share the same functionPersonType.prototype.sayName = function(){ console.log(this.name);}let person = new PersonType('chochi');person.sayName();// person is a instance of obeject and PersonType","text":"Classes1 Class-Like structures in ecma51234567891011121314// propertyfunction PersonType(name){ this.name = name;}// methods: be assigned to the prototype // all instances of the object share the same functionPersonType.prototype.sayName = function(){ console.log(this.name);}let person = new PersonType('chochi');person.sayName();// person is a instance of obeject and PersonType 2 Class in ecma62.1 class declarations basic class declaration : the declaration creates a function called constructor method,which is why typeof PersonClass gives “function “ as the result. are NOT hoisted : runs in strict mode automatically methods are NON-enumberable Can overwrite the calss name outside the class but NOT inside a class method . P1961234567891011121314151617class PersonClass{ // proterties can only be created inside a class constructor or method constructor(_name){ this.name = _name; } // methods: equivalent of PersonClass.prototype.sayName sayName(){ console.log(this.name); }}let person = new PersonClass('chochi');person.sayName();// true trueconsole.log(person instanceof PersonClass,person instanceof Object);// fun fun objconsole.log(typeof PersonClass,typeof PersonClass.prototype.sayName,typeof person); 2.2 Named Class Expressions the PersonClass2 identifier exists only within the class definition 1234567891011let PersonClass = class PerconClass2{ constructor(_name){this.name = _name;} sayName(){ // function console.log(typeof PerconClass2); }}let person = new PersonClass('chochi');person.sayName();console.log(typeof PersonClass);// functionconsole.log(typeof PerconClass2);// undefined 2.3 Class Expressions2.3.1 accessor properties123456789class MyHTML{ constructor(_ele){this.ele = ele;} get html(){ return this.ele.innerHTML; } set html(_value){ this.ele.innerHTML = _value; }} 2.3.2 Generator Methodswaiting /// 2.3.3 Static Members1234567891011121314class PersonClass{ constructor(_name){this.name = _name;} // static method: PersonClass.sayName static classSayName(){ console.log(this.name,this); } // instance methos: PersonClass.prototype.intanceSayName intanceSayName(){ console.log(this.name,this); }}let chochi = new PersonClass('chochi');PersonClass.classSayName();// PersonClasschochi.intanceSayName();//chochi 2.3.4 inheritance with derived classes use super() to specify a constructor of derived classes 最好手动在衍生类的构造函数中调用父类的构造函数 子类必须在constructor方法中调用super方法,否则新建实例时会报错。 这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。 ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。 ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。故,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。 如果子类没有定义constructor方法,默认添加调用父类构造函数,且传入所有参数。 ES6 不会把类的声明提升到代码头部。这种规定的原因与下文要提到的继承有关,必须保证子类在父类之后定义。 Questions1 静态方法和实例方法的区别","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 CALL APPLY 模拟","slug":"Call与Apply","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:54:34.598Z","comments":true,"path":"2019/05/22/Call与Apply/","link":"","permalink":"http://yoursite.com/2019/05/22/Call与Apply/","excerpt":"概念 每个函数都包括两个非继承而来的方法 apply call 在特定的作用域中调用函数,实际上等于设置函数体内this对象的值 看出 call 和 apply 是为了动态改变 this 而出现的区别 apply() 接受两个参数,第一个是运行函数的作用域,第二个是参数数组,参数数组可以用arrar实例,也可以是arguments对象。 call() 参数必须逐个列出来 call 模拟 参数一一对应 12345678Function.prototype.myCall = function(_context){ let context = _context || window;// null -> window context.fn = this; let args = [].slice.call(arguments,1,arguments.length); let result = !args ?context.fn():context.fn(...args); delete context.fn; return result;}","text":"概念 每个函数都包括两个非继承而来的方法 apply call 在特定的作用域中调用函数,实际上等于设置函数体内this对象的值 看出 call 和 apply 是为了动态改变 this 而出现的区别 apply() 接受两个参数,第一个是运行函数的作用域,第二个是参数数组,参数数组可以用arrar实例,也可以是arguments对象。 call() 参数必须逐个列出来 call 模拟 参数一一对应 12345678Function.prototype.myCall = function(_context){ let context = _context || window;// null -> window context.fn = this; let args = [].slice.call(arguments,1,arguments.length); let result = !args ?context.fn():context.fn(...args); delete context.fn; return result;} 参数是数组 apply 模拟1234567Function.prototype.myApply = function(_context,array){ let context = _context || window; context.fn = this; let result = !array ? context.fn() : context.fn(...array); delete context.fn; return result;} 实现 bind123456789101112131415161718Function.prototype.myBind = function () { var self = this, // 保存原函数 context = [].shift.call(arguments), // 保存需要绑定的this上下文 args = [].slice.call(arguments); // 剩余的参数转为数组 return function () { // 返回一个新函数 self.apply(context,[...args]); }}var obj = { name: 'chochi'}function func(a,b,c) { console.log(this.name); console.log(a,b,c);}var func1 = func.myBind(obj,1,2,3);func1(); 参考文献 JavaScript 中 apply 、call 的详解-linxin","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 字符串","slug":"2 字符串","date":"2019-05-22T14:38:04.258Z","updated":"2019-05-22T14:52:15.971Z","comments":true,"path":"2019/05/22/2 字符串/","link":"","permalink":"http://yoursite.com/2019/05/22/2 字符串/","excerpt":"一旦定义无法改变123let str = 'hello';str[1] = '!';console.log(str);// hello 每个字符16位,即2个字节,UTF-16格式存储 length长度放回的可能是不正确的,对于码点在U+1000 - U+10ffff之间的字符,js认为是两字符(es5)","text":"一旦定义无法改变123let str = 'hello';str[1] = '!';console.log(str);// hello 每个字符16位,即2个字节,UTF-16格式存储 length长度放回的可能是不正确的,对于码点在U+1000 - U+10ffff之间的字符,js认为是两字符(es5) Base64 转码 一种编码方法,可以将任意值(只适合ASCII码)转成0~9,A~Z,a~z,+和/这64个个字符组成的可打印字符 主页目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理 12btoa()// 任意值=》Base64atob()// Base64=》原值 12345678// ES5 将 非ASCII码字符转为Base64function b63Encode(str){ return btoa( encodeURIComponent(str)); //非ASCII字符将被十六进制的转义序列进行替换}function b64Decode(str){ return atob(decodeURIComponent(str));}","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 数据格式","slug":"1 数据类型","date":"2019-05-22T14:13:19.650Z","updated":"2019-05-22T14:51:59.748Z","comments":true,"path":"2019/05/22/1 数据类型/","link":"","permalink":"http://yoursite.com/2019/05/22/1 数据类型/","excerpt":"1. null & undefined null表示空值,即该处的值为空 undefined 表示为定义,函数没有返回值时,默认返回undefined","text":"1. null & undefined null表示空值,即该处的值为空 undefined 表示为定义,函数没有返回值时,默认返回undefined 12345678910111213141516171819202122232425if(undefined) //falseif(null) //falseif(undefined == null) //trueif(undefined === null) //falseBoolean([]) //trueBoolean({}) //trueBoolean('') //falseBoolean(false) // falsenew Boolean(false) //trueBoolean(null) //falsenew Boolean(null) //true// 转换为数值Number(null) === 0Number(undefined) === NaN// 类型typeof null === object typeof undefined === undefinedtypeof NaN === number 2. 布尔值 除了以下六个值为转换为false ,其他都视为true undefined null false 0 NaN ‘’ or “” 空对象和空数组对应为 true 3. 整数 & 浮点数 所有数值64位浮点数形式存储,故 1===1.0 底层都是小数存储,但某些运算只有整数才能完成,会自动把64浮点数转为32整数。 小数点前数字多于21位或者小数点后的零多于5个,则自动采用科学计数法3.1 进制,内部自动转化为十进制 0b 二进制 0o 八进制 0x 十六进制3.2 +0 & -0 唯一不同,+0 和 -0 当分母时,一个得到+Infinity,一个得到-Infinity3.3 NaN not a number typeof NaN => number NaN 不等于任何值 (NaN !== NaN) =>true Boolean(NaN) => false 与任何数运算都得到本身 Infinity 与 NaN 做比较,任何情况都返回 false 3.4 与数值相关的全局方法3.4.1 parseInt() 将第一个参数转化为字符串,根据第二个参数(2-36,默认为10)的进制转化为整数 每个字符依次转换,遇到不能转为数字的字符,不在进行,直接返回转好的部分,若整个字符串无法转换,返回NaN 对于自动转换为科学计数法的数字会直接对科学计数法当做字符串转换 1234parseInt('567',2);//NaNparseInt(0x10,16);// 结果为22不是16,因为0x10被自动转换为字符串String(0x10);// 16parseInt(0x10,16) => parseInt( String(0x10), 16 ) => parseInt(‘16’,16) 3.4.2 parseFloat() 将一个字符串转为浮点数,接受科学计数法 自动忽略前导零。 3.4.3 isNaN() 判断一个数值是否为NaN 只对数值有效,其他传入值自动转为数值123function myIsNaN( value ){ return value !== value;} 其他 string number(NAN) boolean undefined object(NULL) function symbol","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"Hello World","slug":"hello-world","date":"2019-05-22T12:55:46.832Z","updated":"2019-05-22T12:55:46.832Z","comments":true,"path":"2019/05/22/hello-world/","link":"","permalink":"http://yoursite.com/2019/05/22/hello-world/","excerpt":"","text":"Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new \"My New Post\" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment","categories":[],"tags":[]}]} \ No newline at end of file +{"meta":{"title":"chochi's workshop","subtitle":null,"description":null,"author":"chochi","url":"http://yoursite.com","root":"/"},"pages":[{"title":"","date":"2019-05-23T03:48:58.628Z","updated":"2019-05-23T03:48:58.628Z","comments":true,"path":"showcase/showcase.html","permalink":"http://yoursite.com/showcase/showcase.html","excerpt":"","text":"chochi's workshop BallGame(正常) IamgeSlider FlexLayout JSONandAJAX(正常) 嵌入框架后项目就乱码了T T 寻找解决方法中"},{"title":"","date":"2019-05-23T03:49:37.681Z","updated":"2019-05-23T03:49:37.681Z","comments":true,"path":"showcase/style.css","permalink":"http://yoursite.com/showcase/style.css","excerpt":"","text":".chochi-container { width: 500px; height: 500px; } .chochi-container a{ color: black; text-decoration-line: none; } .chochi-container h2{ display: block; font-family: Arial, Helvetica, sans-serif; position: relative; margin: auto; margin-top: 120px; } #chochi-Works{ position: relative; top: 30px; margin: auto; display: flex; /* align-items: flex-start; align-items: flex-end; align-items: center; align-items: stretch; */ flex-direction: column; } #chochi-Works div{ border: 1px #cccccc solid; padding: 12px; border-radius: 8px; margin: 8px; height: 50px; box-sizing: border-box; /* width: 150px; */ transition: width .4s ease-in-out; } #chochi-Works div:hover{ width: 300px; border-radius: 10px; background-color: #cccccc; } .chochi-box-1{ flex: 1; width: 200px; } .chochi-box-2{ flex: 1; width: 180px; } .chochi-box-3{ flex: 1; width: 140px; } .chochi-box-4{ flex: 1; width: 220px; }"},{"title":"","date":"2019-05-23T03:01:22.616Z","updated":"2019-05-23T03:01:22.616Z","comments":true,"path":"showcase/works/Ajax/ajax.css","permalink":"http://yoursite.com/showcase/works/Ajax/ajax.css","excerpt":"","text":"#chochi-header{ display: -webkit-flex; display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center; } #chochi-header h1{ font-family: 'Times New Roman', Times, serif; margin: 20px; } #chochi-header button{ font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; background-color: cadetblue; border: none; color: aliceblue; border-radius: 10px; font-size: 16px; outline: none; } #animal-info{ display: none; border: cadetblue 4px dotted; padding: 3%; max-width: 45%; }"},{"title":"","date":"2019-05-23T03:01:14.707Z","updated":"2019-05-23T03:01:14.707Z","comments":true,"path":"showcase/works/Ajax/ajax.html","permalink":"http://yoursite.com/showcase/works/Ajax/ajax.html","excerpt":"","text":"Json and Ajax JSON and AJAX Fetch Info for 3 New Animals"},{"title":"","date":"2019-05-22T15:07:49.095Z","updated":"2019-05-22T11:39:16.649Z","comments":true,"path":"showcase/works/BallGame/BallGame.html","permalink":"http://yoursite.com/showcase/works/BallGame/BallGame.html","excerpt":"","text":"chochi's workshop #gamescreen{ border:1px solid red; } img{ display: none; width: 20px; height: 20px; } BallGame"},{"title":"","date":"2019-05-22T11:39:16.648Z","updated":"2019-05-22T11:39:16.648Z","comments":true,"path":"showcase/works/Ajax/ajax.js","permalink":"http://yoursite.com/showcase/works/Ajax/ajax.js","excerpt":"","text":"var btn = document.getElementById('btn'); var animinalContaniner = document.getElementById('animal-info'); var pageCounter = 1; btn.addEventListener('click',function(){ if( pageCounter > 3 ) return; var ourRequest = new XMLHttpRequest(); ourRequest.open('GET','https://learnwebcode.github.io/json-example/animals-'+ pageCounter +'.json'); ourRequest.onload = function(){ var ourData = JSON.parse(ourRequest.responseText); renderHTML(ourData); }; ourRequest.send(); animinalContaniner.style.display = 'block'; pageCounter++; if( pageCounter > 3 ){ // btn.style.display = 'none'; btn.style.transition = 'visibility 0.2s ease-in-out'; btn.style.visibility = 'hidden'; } }) function renderHTML(data){ var htmlString = \"\"; for(let item of data){ htmlString += '' + item.name + ' is a ' + item.species +'.'; } animinalContaniner.insertAdjacentHTML('beforeend',htmlString); // animinalContaniner.innerHTML = htmlString; }"},{"title":"","date":"2019-05-22T11:39:16.649Z","updated":"2019-05-22T11:39:16.649Z","comments":true,"path":"showcase/works/Ajax/readme.html","permalink":"http://yoursite.com/showcase/works/Ajax/readme.html","excerpt":"","text":""},{"title":"","date":"2019-05-23T03:04:56.030Z","updated":"2019-05-23T03:04:56.030Z","comments":true,"path":"showcase/works/flex/flex.css","permalink":"http://yoursite.com/showcase/works/flex/flex.css","excerpt":"","text":"#chochi-html,#chochi-body{ margin: 0; padding: 0; height: 100%; width: 100%; background-color: darkslategrey; } .chochi-header { height: 100px; text-align: center; position: relative; } .chochi-header h1 { margin-top: 50px; color: aliceblue; font-family: 'Times New Roman', Times, serif; position: absolute; } #chochi-parent { padding: 10px; margin: auto; height: 100%; width: 100%; display: flex; flex-flow: row wrap; align-items: flex-start; justify-content: center; align-content: flex-start; } #chochi-parent div { margin: 10px; padding: 10px; height: 100px; width: 100px; background-color: aliceblue; border-radius: 10%; box-sizing: border-box; box-shadow: 2px 2px 2px darkgray; } #chochi-parent span{ width: 20px; height: 20px; background-color: black; border-radius: 50%; } #chochi-parent .num1 { display: flex; flex-direction: row; align-items: center; justify-content: center; } #chochi-parent .num2 { display: flex; flex-direction: row; justify-content: space-around; align-items: center; } #chochi-parent .num3 { display: flex; flex-direction: row; justify-content: space-around; } #chochi-parent .num3 .item:nth-child(2){ align-self: center; } #chochi-parent .num3 .item:last-child{ align-self: flex-end; } #chochi-parent .num4 div { margin: 0; padding: 0; width: 100px; height: 100px; box-shadow: none; display: flex; justify-content: space-around; align-items: center; } #chochi-parent .num4 { margin-top: 10px; padding: 0; display: flex; flex-direction: column; }"},{"title":"","date":"2019-05-22T11:39:16.674Z","updated":"2019-05-22T11:39:16.674Z","comments":true,"path":"showcase/works/IamgeSlider/style.css","permalink":"http://yoursite.com/showcase/works/IamgeSlider/style.css","excerpt":"","text":"*{ padding: 0px; margin: 0px; box-sizing: border-box; } .container{ width: 628px; margin: auto; overflow: hidden; position: relative; } .slider{ display: flex; width: 100%; height: 100%; } .btn{ position: absolute; width: 10%; height:7%; background: transparent; border: 0px; outline: none; } #prevBtn{ top:50%; left: 5%; } #nextBtn{ top:50%; right: 5%; }"},{"title":"","date":"2019-05-22T11:39:16.657Z","updated":"2019-05-22T11:39:16.657Z","comments":true,"path":"showcase/works/IamgeSlider/ImageSlider.js","permalink":"http://yoursite.com/showcase/works/IamgeSlider/ImageSlider.js","excerpt":"","text":"const slider = document.querySelector('.slider'); const imgs = document.querySelectorAll('.slider img'); // buttons const prevBtn = document.querySelector('#prevBtn'); const nextBtn = document.querySelector('#nextBtn'); // counter let counter = 1; let size = imgs[0].clientWidth; slider.style.transform = 'translateX(' + (-size * counter) + 'px)'; function clickNext(){ if(counter>=imgs.length-1) return;//防止快速点击 transitionend事件未监听到 slider.style.transition= 'transform 0.2s ease-in-out'; counter++; slider.style.transform = 'translateX(' + (-size * counter) + 'px)'; } function clickPrev(){ if(counter{ // console.log(counter); if(imgs[counter].id ==='lastClone'){ slider.style.transition = 'none';//直接替换不要渐进 counter = imgs.length - 2; slider.style.transform = 'translateX(' + (-size * counter) + 'px)'; } if(imgs[counter].id ==='firstClone'){ slider.style.transition = 'none'; counter = imgs.length - counter; // console.log(imgs.length,counter); slider.style.transform = 'translateX(' + (-size * counter) + 'px)'; } });"},{"title":"","date":"2019-05-22T11:39:16.657Z","updated":"2019-05-22T11:39:16.657Z","comments":true,"path":"showcase/works/IamgeSlider/IamgeSlider.html","permalink":"http://yoursite.com/showcase/works/IamgeSlider/IamgeSlider.html","excerpt":"","text":"Full screen image slider"},{"title":"","date":"2019-05-23T03:04:59.199Z","updated":"2019-05-23T03:04:59.199Z","comments":true,"path":"showcase/works/flex/flex.html","permalink":"http://yoursite.com/showcase/works/flex/flex.html","excerpt":"","text":"flex layout FLEX LAYOUT"},{"title":"","date":"2019-05-22T11:39:16.675Z","updated":"2019-05-22T11:39:16.675Z","comments":true,"path":"showcase/works/flex/readme.html","permalink":"http://yoursite.com/showcase/works/flex/readme.html","excerpt":"","text":"flex layout"},{"title":"","date":"2019-05-22T11:39:16.655Z","updated":"2019-05-22T11:39:16.655Z","comments":true,"path":"showcase/works/BallGame/src/index.js","permalink":"http://yoursite.com/showcase/works/BallGame/src/index.js","excerpt":"","text":"import {Game} from './game.mjs'; const canvas = document.querySelector('#gamescreen'); const ctx = canvas.getContext('2d'); const GAME_WIDTH = 800; const GAME_HEIGHT = 600; ctx.clearRect(0,0,800,600); let game = new Game(GAME_WIDTH,GAME_HEIGHT); // game.start(); let lastTime = 0; //let imgBall = document.querySelector('#ball'); function gameLoop(timeStamp){ let deltaTime = timeStamp - lastTime; lastTime = timeStamp; ctx.clearRect(0,0,GAME_WIDTH,GAME_HEIGHT); game.update(deltaTime); game.draw(ctx); requestAnimationFrame(gameLoop); } gameLoop();"}],"posts":[{"title":"ECMA5 继承","slug":"继承","date":"2019-05-22T14:38:04.278Z","updated":"2019-05-22T14:48:03.891Z","comments":true,"path":"2019/05/22/继承/","link":"","permalink":"http://yoursite.com/2019/05/22/继承/","excerpt":"2 继承ECMAScript 只支持实现继承,不支持接口继承。 继承方法类型: 原型链继承 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承2.1 原型链继承 基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法,实现的本质是重写原型对象,代之一个新类型的实例 原型对象可以算是是一个‘实例’,有用constructor指针,指向其构造函数 构造函数有prototype指针指向原型对象 实例有proto指针执行其原型对象 Father().prototype —> Father.prototype [原型对象] Father.prototype.constructor –> Father() [构造函数] InstanceOfFather. proto –> Father.prototype 问题: 引用类型的原型属性会被所有实例共享 注意代码块中原型链继承的tips 在创建子类的实例时,不能像超类中的构造函数传递参数","text":"2 继承ECMAScript 只支持实现继承,不支持接口继承。 继承方法类型: 原型链继承 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承2.1 原型链继承 基本思想:利用原型让一个引用类型继承另一个引用类型的属性和方法,实现的本质是重写原型对象,代之一个新类型的实例 原型对象可以算是是一个‘实例’,有用constructor指针,指向其构造函数 构造函数有prototype指针指向原型对象 实例有proto指针执行其原型对象 Father().prototype —> Father.prototype [原型对象] Father.prototype.constructor –> Father() [构造函数] InstanceOfFather. proto –> Father.prototype 问题: 引用类型的原型属性会被所有实例共享 注意代码块中原型链继承的tips 在创建子类的实例时,不能像超类中的构造函数传递参数 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 //构造函数 function Father(){ this.name = 'Big Dady'; this.title = 'father'; } //实例方法 Father.prototype.sayName = function (){ console.log(this.name); } //构造函数 function Son(){ this.title = 'son'; this.age = 19; this.objInSonInstance = { sister: 'chesnut' } }//-------------------- tips 原型链继承 存疑中 ----------------------------------- // Son 继承 Father的一个实例 // Father() 中所有属性被衍生类共享 // 只不过普通属性被更改了binding,在实例中拥有了该属性,不会再像原型链搜素 // 引用属性除非是直接更改binding,否则是所有实例都共享了这个属性 Son.prototype = new Father();//------------------------------------------------------------------------------- Son.prototype.objInSon={ brother: 'flag' } //Son的实例方法: !先继承再添加子类的实例方法,不然会被覆盖! Son.prototype.sayTitle = function(){ console.log(this.title); } //在类上的静态方法 Son.staticMethod = function(){ console.log('static!!!'); } //创建Son类的一个实例 instance let instance = new Son(); let instance2 = new Son(); /** instance 的属性搜索链: instance properties: age,title(son),objInSonInstance 以下为原型链层,所有引用的属性会被共享(函数也算对象,对象是引用类型,所有实例共享引用类型、函数) __proto__ properties: name,title(father),sayTitle,objInSon __proto__.__proto__ properties: sayName **/ console.log(instance.hasOwnProperty('title')); //true console.log(instance.__proto__.hasOwnProperty('title')); //true console.log(instance.__proto__.__proto__.hasOwnProperty('sayName')); //true console.log(instance.title, instance.__proto__.title); //son,father console.log(Son.hasOwnProperty('staticMethod')); //true // 实例引用属性,互不影响 instance.objInSonInstance.addInInstance = 'instance add'; console.log(instance.objInSonInstance,instance2.objInSonInstance); //原型上引用属性被共享,instance2.objInSon 被更改 instance.objInSon.addInPrototype = 'prototype add'; console.log(instance.objInSon,instance2.objInSon); 2.2 借用构造函数 借用构造函数并无构成真正意义上的继承 可以传参,引用类型不会被共享,但无法达到函数复用的目的。 1234567891011121314151617181920//借用构造函数 function Super(){ this.refType = [1,2,3]; this.basicType = 'Super basic type';}//Sub不可用该方法Super.prototype.printData = function (property){ console.log(this[property]);}// Sub的原型对象还是objectfunction Sub(){ Super.call(this);}let in1 = new Sub();let in2 = new Sub();console.log(in1.__proto__,Sub.prototype);// object objectin1.printData('refType');//error: not a functionin1.refType.push(1);console.log(in2.refType);//1,2,3 2.3 原型式继承 一个对象作为另外一个对象的继承,原型对象的所有属性被共享,故达到函数复用目的 1234567891011121314151617// 一个对象实例,作为模板let Person = { name:'chochi', // 子类赋值重写,所有看起来不被共享 habbits:['reading','speaking'], print: function(){ console.log(this.name,this.habbits); }}//浅复制let chochi = Object.create(Person);let chesnut = Object.create(Person);chochi.habbits.push('eating');chesnut.print();//reading speaking eatingconsole.log(chesnut.print===chochi.print);// true:函数复用 2.4 组合继承 概念: 使用原型链实现对需要共享的属性和方法的继承 借用构造函数完成实例属性的继承 实例属性屏蔽原型属性 可被 instanceof , isPrototypeOf 识别 融合优点,最常用 问题: 调用两次构造函数,一次是创建子类原型,一次是子类构造函数内部。—》 解决:寄生组合式继承12345678910111213141516171819202122232425 function Father(_title){ this.refTitle ={ title: _title }; } Father.prototype.printProperty = function (){ console.log(this.refTitle); } function Son(_title,_age){ // 借用构造函数:创建实例属性 Father.call(this,_title); this.age = _age; /* 实例属性 property: age, refTitle{title} */ } // 重写原型:共享方法 // 原型上也有了 refTitle 属性,虽然被实例属性屏蔽了,等于一个属性存在了两次 Son.prototype = new Father();//------------ tips --------------------------// 将指针值回来除了逻辑更加清晰其他的改变? Son.prototype.constructor = Son;//-------------------------------------------- 2.5 寄生组合继承 可以直接简化成下面 将组合继承的原型重写那一步改成以下: 如此就不用call两次构造函数,属性也不会被重复 1Son.prototype = Father.prototype;","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 包装对象","slug":"7 包装对象 wrapper","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:49:12.973Z","comments":true,"path":"2019/05/22/7 包装对象 wrapper/","link":"","permalink":"http://yoursite.com/2019/05/22/7 包装对象 wrapper/","excerpt":"1 定义 数值、字符串、布尔值这三种原型类型的值,在一听条件下也会自动转化为对象,也就是原始类型的包装对象。 Number String Boolean 包装对象的目的,是得对象模型覆盖js所优质,正门语言都有一个通用的数据模型,其次是得原始类型的值也有可以调动自己的方法。 原始类型的值会自动当做包装对象调用,即调用包装对象的属性和方法。JS引擎糊自动将原始类型的值转换为包装对象实例,并在使用后立即销毁。 自动转换生成的包装对象是只读的,无法修改。 1234567891011var str = 'abc';str.length; // 3// 等同于var strObj = new String(str);/* String{ 0:\"1\",1:\"b\",2;\"c\",length:3[[PrimitiveValue]]:\"abc\" } strObj.length;//3*/","text":"1 定义 数值、字符串、布尔值这三种原型类型的值,在一听条件下也会自动转化为对象,也就是原始类型的包装对象。 Number String Boolean 包装对象的目的,是得对象模型覆盖js所优质,正门语言都有一个通用的数据模型,其次是得原始类型的值也有可以调动自己的方法。 原始类型的值会自动当做包装对象调用,即调用包装对象的属性和方法。JS引擎糊自动将原始类型的值转换为包装对象实例,并在使用后立即销毁。 自动转换生成的包装对象是只读的,无法修改。 1234567891011var str = 'abc';str.length; // 3// 等同于var strObj = new String(str);/* String{ 0:\"1\",1:\"b\",2;\"c\",length:3[[PrimitiveValue]]:\"abc\" } strObj.length;//3*/ 2 Boolean2.1 if ()12if ( new Boolean(flase)) // true 逻辑运算,所有对象为trueif ( new Boolean(false).valueOf())//false 返回实例原始值 3 正则表达式3.1 建立 字面量方法在引擎编译代码的时候建立正则表达式,所以较为高效12var regex = /xyz/; // 编译时建立var regex = new RegExp('xyz'); // 运行时建立 3.2 实例属性1234567//以下属性只读 // 返回布尔值 是否有设置当前修饰 regex.ignoreCase; regex.global; regex.multiline; // 返回字符串,包含已经设置的所有修饰符,按字母排序 regex.flags; 3.3 实例方法 RegExp.prototype.test() 从 lastIndex 位置向后匹配,找到当前模式能匹配的参数字符串则返回 true 带有g修饰符,每次test()都从上一次结束的位置开始向后匹配1234567var regex = /r/g;var str = '_x_x';regex.lastIndex ; // 0regex.test(s); //trueregex.lastIndex; // 2 _regex.lastIdex = 4; // 可指定搜索位置,只对同一个正则表达式有效regex.test(s); //false RegExp.prototype.exec() 返回匹配结果(数组) 包含 input index 属性 12345678910var r = /a(b+)a/;var match = r.exec('_abbbbba_aba_');console.log(match);/* Array(2) [\"abbbbba\", \"bbbbb\"] index:1 整个匹配模式成功的开始位置 input:\"_abbbbba_aba_\" 整个字符串 length:2 第二个成员是组匹配结果*/ 3.4 字符串的实例方法 match() 返回匹配结果 若带 g 修饰,则一次性返回所有结果 正则表达式的 lastIndex 属性不造成影响123var s = 'abba_aba_abaa';var r = /a(b+)a/g;var results = s.match(r);//Array(3) [\"abba\", \"aba\", \"aba\"] search() 返回第一个满足条件的匹配结果在整个字符串中的位置 replace(search,replacement) 若带 g 修饰符,则替换所有匹配成功的项","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 函数","slug":"4 函数","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:53:07.745Z","comments":true,"path":"2019/05/22/4 函数/","link":"","permalink":"http://yoursite.com/2019/05/22/4 函数/","excerpt":"1 概述1.1 重复声明 函数的声明会提升到函数定义时所在的作用域的头部。故同名函数会被后来的函数替代。 12345678function f(){ console.log('one');}f(); //twofunction f(){ console.log('two');}f(); //two","text":"1 概述1.1 重复声明 函数的声明会提升到函数定义时所在的作用域的头部。故同名函数会被后来的函数替代。 12345678function f(){ console.log('one');}f(); //twofunction f(){ console.log('two');}f(); //two 1.2 函数名的提升 函数声明会提升 12f(); // its okfunction f(){} 函数表达式不提升 使用 var ,var变量提升 ,可识别到变量被声明,但没有定义。 使用 let ,变量未定义。123456789 f(); // f is not a function var f = function(){};//等同于 var f; f(); f = function(){};//使用 let f(); // f is not defined let f = function(){}; 2 函数的属性和方法2.1 name 返回函数的名字2.2 length 返回函数预期传入参数的个数2.3 toString() 返回一个字符串,内容是函数的源码 123456 // 可实现多行字符串 function f(){/* 这是一个 多行注释 */}f.toString() 3 函数作用域3.1 定义 es5 中:全局和函数作用域。 对于 var 命令, 局部变量只能在函数内部声明,其他块区中声明一律为全局变量。3.2 函数内部的变量提升 var,函数声明都会提升到函数体头部3.3 函数本身的作用域 函数本身的作用域就是其声明时所在的作用域,与其运行所在的作用域无关。123456789101112var a = false ;var inside = function(){ console.log(a);}function outside(){ var a = true; inside();}outside(); // false 123456789101112var a = false ;function outside(){ var a = true; var inside = function(){ console.log(a); } inside();}outside(); // true 4 参数 传递方式 passes by value 允许有不定数目的参数4.1 arguments 对象 正常模式下, arguments 允许运行时修改 该对象的 length 属性,可以判断函数调用时到底带几个参数。 callee 属性,指向对应的原函数。 5 闭包 读取函数内部的变量 闭包可以使得诞生环节一直存在,内部变量记住上一次调用时的运算结果 封装对象的私有属性和私有方法 外层函数每次运行,都会生成一个新闭包。每一个闭包变量独立,不共享。 闭包的内存消耗很大,会造成网页的性能问题。 12345678function createIncrementor(start){ return function(){ return start++; }}var ins = createIncrementor(0);ins(); // 0ins(); // 1 6 立即调用的函数表达式 IIFE function 关键字出现在行首一律解释为语句。让引擎理解为表达式,普通的方法是将函数放在括号里。 1(function(){/* code */})(); 不必为函数命名,避免污染全局变量。 形成单独的作用域,封装外部无法读取的私有变量。7 eval 使用别名调用一律为全局作用域。","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 this指针","slug":"关于 this 指针","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:54:45.463Z","comments":true,"path":"2019/05/22/关于 this 指针/","link":"","permalink":"http://yoursite.com/2019/05/22/关于 this 指针/","excerpt":"1 概念 this 对象时运行时基于函数的执行环节绑定的,在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。 匿名函数的执行环节具有全局性,因此this指针对象通常指向window 12345678910let obj = { fun : function(){ console.log(this);//obj return function(){ console.log(this);//window 匿名函数有全局性 }; }};","text":"1 概念 this 对象时运行时基于函数的执行环节绑定的,在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。 匿名函数的执行环节具有全局性,因此this指针对象通常指向window 12345678910let obj = { fun : function(){ console.log(this);//obj return function(){ console.log(this);//window 匿名函数有全局性 }; }}; 每个函数在被调用的时候都被自动取得两个特殊的变量:this & arguments 。 内部函数在搜索这两个变量的时候,只会搜索到其活动对象位置,因此不可能直接访问外部函数中的这两个变量。 可以将外部作用域中的this对象保存在一个闭包能访问的变量里1234567891011let obj = { fun : function(){ console.log(this);//obj let that = this; return function(){ console.log(that);//obj 函数闭包把that包括进来 }; } };","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 标准库","slug":"5 标准库","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:53:23.277Z","comments":true,"path":"2019/05/22/5 标准库/","link":"","permalink":"http://yoursite.com/2019/05/22/5 标准库/","excerpt":"1 判断某个变量是否为函数123function isObject(value){ return value === Object(value); } 2 对象的键名","text":"1 判断某个变量是否为函数123function isObject(value){ return value === Object(value); } 2 对象的键名 12Object.keys // 返回对象本身(不包括继承)的可枚举属性Object.getOwnPropertyNames // 返回对象本身的所有属性(不包括继承) 3 判断数据类型 toString 返回对象的类型字符串,因此可以用来判断一个值的类型,返回的第一个值表示该值的构造函数。 但由于实力对象可能会自定义该方法,所有调用原型上的方法。1Object.prototype.toString.call(value) 4 属性描述对象 value writable 是否可写 enumerable 是否可枚举 值为false时 for..in Object.keys 会跳过该属性 configurable 空值属性描写对象的可写性 get set 1Object.getOwnPropertyDescriptor(obj,PropertyName) // 活动对象本身属性描述对象 12345678910// 使用属性描述对象定义或修改一个属性var obj = Object.defineProperty({},'p',{ value:123, writable:false, enumerable:true, configurable:false});obj.p=456;obj.p; //123 若一个属性的enumerable为false,以下操作不会取到该属性 for … in Object.keys 5 对象的拷贝1234567891011var extend = function (to,from){ for( let property in from){ if(!from.hasOwnProperty(property))continue; Object.defineProperty( to, property, Object.getOwnPropertyDescriptor(from,property) // 读不到继承属性的属性描述对象 ); } return to;} 6 控制对象的状态 冻结对象 1234 // 弱到强Object.preventExtensions(obj);// 无法添加新属性Object.seal(obj);// 无法添加or删除属性Object.freeze(obj);//无法添加or删除属性,无法改变属性的值,该对象实际上变成了常量 以上方法,可以改变原型对象,来为对象增加属性","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 数组","slug":"6 Array","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:53:38.911Z","comments":true,"path":"2019/05/22/6 Array/","link":"","permalink":"http://yoursite.com/2019/05/22/6 Array/","excerpt":"1 静态方法1.1 判断是否为数组 使用Array的静态方法 1Array.isArray( array ) 使用原型toString方法,返回的字符串第二个词表示构造函数 1Object.prototype.toString.call( array ) // [object array]","text":"1 静态方法1.1 判断是否为数组 使用Array的静态方法 1Array.isArray( array ) 使用原型toString方法,返回的字符串第二个词表示构造函数 1Object.prototype.toString.call( array ) // [object array] instanceof (不太靠谱) 12[] instanceof Object // true[] instanceof Array // true 2 实例方法 valueOf() 返回数组本身 toString() 返回数组字符串形式 push() 在数组的末端添加一个或多个元素 返回数组长度 pop() 删除数组最后一个元素 返回被删除的元素 shift() 删除数组第一个元素 返回被删除的元素 unshitf() 在数组第一个位置添加元素 返回数组长度 实例方法 ————| 操作 | 参数 | 返回 | 是否改变原数组 | 其他 || :—– | :—- | :—- | :— | :—- | :—- || valueOf()||| 返回数组本身 | 否 | || toString()|| | 返回数组字符串形式 | 否 | || push() | 在数组的末端添加一个或多个元素 | 添加的元素 | 返回数组长度 |是||| pop() | 删除数组最后一个元素 | 无 | 返回被删除的元素|是||| shift() | 删除数组第一个元素 | 无 | 返回被删除的元素|是||| unshitf() | 在数组第一个位置添加元素 | 添加的元素 | 返回数组长度|是||| join()|以参数为分隔符,将数组成员链接为一个字符串| 分隔符|返回字符串|否|undefined or null or hole 转为空字符串||cantact()|链接多个数组|数组|返回一个新数组|否|数组浅拷贝(对象涉及引用问题)||recerse()|反转数组|无|改变后的数组|是|||slice()| 提取数组的一部分|start,end(允许负数)|返回新数组|否|参数不合理则返回空数组||splice()|删除原数组的一部分,可在删除的位置添加新成员|start,cnt,addItem1,add..|返回被删除的元素|是|start接受负数||sort()|对原数组进行排序,默认字典序|自定义比较函数||是|数值也会被默认转为字符串||map()|成员依次执行函数,返回执行结果组成的数组|(fun(item,index,arr),obj)函数后两项可省略,obj用来绑定this|返回结果组成的新数组|否|只跳过hole,undefined & null 不跳过||forEach()|依次执行参数函数,不返回|同上|无|否|无法中断执行,同上||filter()|满足条件的成员组成新数组返回|同上|满足条件的成员组成新数组返回|否|||every()|所有成员返回true,则结果返回true|同上|布尔值|否|||reduce()|依次处理每个成员,最终累计为一个值|fun(sum,curItem,index,arr)前两个必须|sum|否|||indexf()|参数在数组中第一次出现的位置|搜索的元素|下标 or -1 | 否|内部搜索使用 ===|","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 对象","slug":"3 对象","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:52:44.830Z","comments":true,"path":"2019/05/22/3 对象/","link":"","permalink":"http://yoursite.com/2019/05/22/3 对象/","excerpt":"1 键名 对象的所有键名都是字符串,若键名不符合标识符的条件,则必须加上引号。 如果使用方运算符,键名必须放在引号里,否则会被当做变量处理。 数字键可以不加引号,会自动转成字符串。123456let obj = { flag: true };obj[flag] // undefinedobj.flag // trueobj.['flag'] // trueflag ='flag';obj[flag] // ture","text":"1 键名 对象的所有键名都是字符串,若键名不符合标识符的条件,则必须加上引号。 如果使用方运算符,键名必须放在引号里,否则会被当做变量处理。 数字键可以不加引号,会自动转成字符串。123456let obj = { flag: true };obj[flag] // undefinedobj.flag // trueobj.['flag'] // trueflag ='flag';obj[flag] // ture 对象的每一个键名又称为属性 property,它的键值可以是任何数据类型。2 属性2.1 属性的查看 查看对象本身的所有可枚举属性1Object.keys 2.2 属性的删除 只能删除对象本身的属性,无法删除继承得来的属性。 使用 delete 删除完对象的属性后,Object.keys 方法的返回值也不再包括该属性。 只有一种情况 delete 命令返回 false ,该属性存在但不可删除 configurable:false2.3 属性是否存在 ‘PropertyName’ in obj :是否存在该属性,包括继承而来 hasOwnProperty(‘PropertyName’) :对象本身是拥有该属性2.4 属性的遍历 遍历所有可枚举的属性,包括继承而来的 1for...in 遍历所有可枚举的本身属性(enumerable) 123456// 遍历对象本身属性for( let key in obj){ if( obj.hasOwnProperty(key)){ /* do some operations */ }} 2.5 with 语句 with 语句内只能创建全局变量。 with的绑定对象不明确所以弄临时变量代替with123with( obj ){ /** do operations **/} 遍历总结 for.. in 包括继承而来的可枚举属性 Object.keys 不包括继承的的可枚举属性 Object.getOwnPropertyNames 本身的所有属性","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA6 类","slug":"9 JavaScript Classes","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:54:09.225Z","comments":true,"path":"2019/05/22/9 JavaScript Classes/","link":"","permalink":"http://yoursite.com/2019/05/22/9 JavaScript Classes/","excerpt":"Classes1 Class-Like structures in ecma51234567891011121314// propertyfunction PersonType(name){ this.name = name;}// methods: be assigned to the prototype // all instances of the object share the same functionPersonType.prototype.sayName = function(){ console.log(this.name);}let person = new PersonType('chochi');person.sayName();// person is a instance of obeject and PersonType","text":"Classes1 Class-Like structures in ecma51234567891011121314// propertyfunction PersonType(name){ this.name = name;}// methods: be assigned to the prototype // all instances of the object share the same functionPersonType.prototype.sayName = function(){ console.log(this.name);}let person = new PersonType('chochi');person.sayName();// person is a instance of obeject and PersonType 2 Class in ecma62.1 class declarations basic class declaration : the declaration creates a function called constructor method,which is why typeof PersonClass gives “function “ as the result. are NOT hoisted : runs in strict mode automatically methods are NON-enumberable Can overwrite the calss name outside the class but NOT inside a class method . P1961234567891011121314151617class PersonClass{ // proterties can only be created inside a class constructor or method constructor(_name){ this.name = _name; } // methods: equivalent of PersonClass.prototype.sayName sayName(){ console.log(this.name); }}let person = new PersonClass('chochi');person.sayName();// true trueconsole.log(person instanceof PersonClass,person instanceof Object);// fun fun objconsole.log(typeof PersonClass,typeof PersonClass.prototype.sayName,typeof person); 2.2 Named Class Expressions the PersonClass2 identifier exists only within the class definition 1234567891011let PersonClass = class PerconClass2{ constructor(_name){this.name = _name;} sayName(){ // function console.log(typeof PerconClass2); }}let person = new PersonClass('chochi');person.sayName();console.log(typeof PersonClass);// functionconsole.log(typeof PerconClass2);// undefined 2.3 Class Expressions2.3.1 accessor properties123456789class MyHTML{ constructor(_ele){this.ele = ele;} get html(){ return this.ele.innerHTML; } set html(_value){ this.ele.innerHTML = _value; }} 2.3.2 Generator Methodswaiting /// 2.3.3 Static Members1234567891011121314class PersonClass{ constructor(_name){this.name = _name;} // static method: PersonClass.sayName static classSayName(){ console.log(this.name,this); } // instance methos: PersonClass.prototype.intanceSayName intanceSayName(){ console.log(this.name,this); }}let chochi = new PersonClass('chochi');PersonClass.classSayName();// PersonClasschochi.intanceSayName();//chochi 2.3.4 inheritance with derived classes use super() to specify a constructor of derived classes 最好手动在衍生类的构造函数中调用父类的构造函数 子类必须在constructor方法中调用super方法,否则新建实例时会报错。 这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。 ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。 ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。故,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。 如果子类没有定义constructor方法,默认添加调用父类构造函数,且传入所有参数。 ES6 不会把类的声明提升到代码头部。这种规定的原因与下文要提到的继承有关,必须保证子类在父类之后定义。 Questions1 静态方法和实例方法的区别","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 CALL APPLY 模拟","slug":"Call与Apply","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:54:34.598Z","comments":true,"path":"2019/05/22/Call与Apply/","link":"","permalink":"http://yoursite.com/2019/05/22/Call与Apply/","excerpt":"概念 每个函数都包括两个非继承而来的方法 apply call 在特定的作用域中调用函数,实际上等于设置函数体内this对象的值 看出 call 和 apply 是为了动态改变 this 而出现的区别 apply() 接受两个参数,第一个是运行函数的作用域,第二个是参数数组,参数数组可以用arrar实例,也可以是arguments对象。 call() 参数必须逐个列出来 call 模拟 参数一一对应 12345678Function.prototype.myCall = function(_context){ let context = _context || window;// null -> window context.fn = this; let args = [].slice.call(arguments,1,arguments.length); let result = !args ?context.fn():context.fn(...args); delete context.fn; return result;}","text":"概念 每个函数都包括两个非继承而来的方法 apply call 在特定的作用域中调用函数,实际上等于设置函数体内this对象的值 看出 call 和 apply 是为了动态改变 this 而出现的区别 apply() 接受两个参数,第一个是运行函数的作用域,第二个是参数数组,参数数组可以用arrar实例,也可以是arguments对象。 call() 参数必须逐个列出来 call 模拟 参数一一对应 12345678Function.prototype.myCall = function(_context){ let context = _context || window;// null -> window context.fn = this; let args = [].slice.call(arguments,1,arguments.length); let result = !args ?context.fn():context.fn(...args); delete context.fn; return result;} 参数是数组 apply 模拟1234567Function.prototype.myApply = function(_context,array){ let context = _context || window; context.fn = this; let result = !array ? context.fn() : context.fn(...array); delete context.fn; return result;} 实现 bind123456789101112131415161718Function.prototype.myBind = function () { var self = this, // 保存原函数 context = [].shift.call(arguments), // 保存需要绑定的this上下文 args = [].slice.call(arguments); // 剩余的参数转为数组 return function () { // 返回一个新函数 self.apply(context,[...args]); }}var obj = { name: 'chochi'}function func(a,b,c) { console.log(this.name); console.log(a,b,c);}var func1 = func.myBind(obj,1,2,3);func1(); 参考文献 JavaScript 中 apply 、call 的详解-linxin","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 面向对象编程","slug":"9 面向对象编程","date":"2019-05-22T14:38:04.268Z","updated":"2019-05-22T14:48:49.890Z","comments":true,"path":"2019/05/22/9 面向对象编程/","link":"","permalink":"http://yoursite.com/2019/05/22/9 面向对象编程/","excerpt":"1 实例对象与new 命令1.1 构造函数 函数体内部使用了 this 关键字,代表了所要生成的对象实例。 生成对象的时候,必须使用 new 命令 函数名首字母大写,以示区别。 1.2 new 命令 执行构造函数,返回一个对象实例。 1.2.1 new 原理1234graph TB A[1.创建一个空对象作为将要返回的对象实例]--> B[2.将这个空对象的原型指向构造函数的prototype属性] B-->C[3.将空对象赋值给函数内部的this关键字] C-->D[4.开始执行构造函数内部的代码]","text":"1 实例对象与new 命令1.1 构造函数 函数体内部使用了 this 关键字,代表了所要生成的对象实例。 生成对象的时候,必须使用 new 命令 函数名首字母大写,以示区别。 1.2 new 命令 执行构造函数,返回一个对象实例。 1.2.1 new 原理1234graph TB A[1.创建一个空对象作为将要返回的对象实例]--> B[2.将这个空对象的原型指向构造函数的prototype属性] B-->C[3.将空对象赋值给函数内部的this关键字] C-->D[4.开始执行构造函数内部的代码] 12345678910111213function _new(constructor,params){ var args = [].slice.call(arguments); var constructor = args.shift(); // 创建一个空对象,继承构造函数的prototype属性 var context = Object.create(constructor.prototype); //执行构造函数 var result = constructor.apply(context, args); //返回结构是对象就直接返回,否则返回一个空对象 return (typeof result === 'object' && result != null) ? result : context;} 1.2.2 new.target 如果当前函数是new命令调用的,new.target指向当前函数,否则为 undefined 使用该属性判断函数调用的时候是否使用了new命令。 2 this 关键字 this 就是属性或方法“当前”所在的对象 this 的指向是可变的 2.1 this 实质1var obj = { foo : 5 }; 1.引擎会在内存中生成一个对象{ foo : 5 } 2.把这个对象的内存地址赋值给变量obj 3.若属性的值是一个函数,引擎会将函数单独保存在内存中,如何再讲函数的地址赋值给foo属性的value属性。 this 的目的在函数体内部,只带函数当前的运行环境。 123456{ foo:{ [[value]]: reference of function .... }} 2.2 this 的使用场合全局环境 只有在全局环节下运行,this就是指顶层对象 window 构造函数 在构造函数中的 this ,指的是实例对象 对象的方法 如果对象的方法里面包含this, this的执行就是方法运行时所在的对象,该方法赋值给另一个对象,就会改变this指向。 若将对象内部或者嵌套对象内部的方法赋值给一个变量,this会指向全局变量。1234567891011121314var a = { b:{ method : function(){ console.log(this); } }, method:function(){ console.log(this); }};var textb = a.b.method;textb(); // windowvar texta = a;a.method(); // object a 在函数中定义的匿名函数的this指向全局对象2.3 绑定 this 使用 call,apply,bind,切换/固定this指向。 bind 函数每运行一次,就返回一个新函数,故监听和回调事件的时候需注意 12345678910111213var counter = { cnt : 0, increament:function(){ 'use strict'; this.cnt++; }}function callIt(callback){ callback();}callIt( counter.increament.bind(counter) ); // 绑定对象,如果直接传函数的referce则this变为windowcounter.cnt; //1 在非 use strict 的情况下可改变为window,在严格模式下报错undefined 1234567891011121314var cnt = 100;var counter = { cnt : 0, increament:function(){ this.cnt++; }}function callIt(callback){ callback();}callIt( counter.increament);// this 指向变为windowconsole.log(counter.cnt,cnt); // 0 101 2.3.1 bind留与call方法使用1234var push = Function.prototype.call.bind(Array.prototype.push);var a = [1,2,3];push(a,4);a; // [1,2,3,4] 3 ES5 对象的继承 js的继承通过“原型对象” prototype 实现。 3.1 原型对象概述 缺点:实例之间无法共享属性 123456789function Cat(_name){ this.name = _name; // 每个实例都会创建一次这个方法 ins1.meow !== ins2.meow // 使用prototype属性解决 this.meow = function(){ console.log('miao!~'); }} 3.2 prototype 属性 定义所有实例对象共享的属性和方法,而实例可以视作从原型对象衍生处理的子对象。 3.3 原型链 prototype chain 所有对象都继承了Object.proto的属性。123// 原型链尽头是 null Object.getPrototypeOf(Object.prototype); // nullObject.prototype.__proto__; // null 等价写法 3.4 constructor 属性 prototype 对象有constructor属性,默认指向prototype对象所在的构造函数。 可以被实例对象继承。使实例对象能被知晓是被哪个构造函数产生。 可以使用 constructor 属性 从一个实例对象新建另一个实例。 constructor属性表示原型对象与构造函数直接的关联关系,如果修改了原型对象,需要同时修改constructor属性。 跳 对象的相关方法","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 字符串","slug":"2 字符串","date":"2019-05-22T14:38:04.258Z","updated":"2019-05-22T14:52:15.971Z","comments":true,"path":"2019/05/22/2 字符串/","link":"","permalink":"http://yoursite.com/2019/05/22/2 字符串/","excerpt":"一旦定义无法改变123let str = 'hello';str[1] = '!';console.log(str);// hello 每个字符16位,即2个字节,UTF-16格式存储 length长度放回的可能是不正确的,对于码点在U+1000 - U+10ffff之间的字符,js认为是两字符(es5)","text":"一旦定义无法改变123let str = 'hello';str[1] = '!';console.log(str);// hello 每个字符16位,即2个字节,UTF-16格式存储 length长度放回的可能是不正确的,对于码点在U+1000 - U+10ffff之间的字符,js认为是两字符(es5) Base64 转码 一种编码方法,可以将任意值(只适合ASCII码)转成0~9,A~Z,a~z,+和/这64个个字符组成的可打印字符 主页目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理 12btoa()// 任意值=》Base64atob()// Base64=》原值 12345678// ES5 将 非ASCII码字符转为Base64function b63Encode(str){ return btoa( encodeURIComponent(str)); //非ASCII字符将被十六进制的转义序列进行替换}function b64Decode(str){ return atob(decodeURIComponent(str));}","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"ECMA5 数据格式","slug":"1 数据类型","date":"2019-05-22T14:13:19.650Z","updated":"2019-05-22T14:51:59.748Z","comments":true,"path":"2019/05/22/1 数据类型/","link":"","permalink":"http://yoursite.com/2019/05/22/1 数据类型/","excerpt":"1. null & undefined null表示空值,即该处的值为空 undefined 表示为定义,函数没有返回值时,默认返回undefined","text":"1. null & undefined null表示空值,即该处的值为空 undefined 表示为定义,函数没有返回值时,默认返回undefined 12345678910111213141516171819202122232425if(undefined) //falseif(null) //falseif(undefined == null) //trueif(undefined === null) //falseBoolean([]) //trueBoolean({}) //trueBoolean('') //falseBoolean(false) // falsenew Boolean(false) //trueBoolean(null) //falsenew Boolean(null) //true// 转换为数值Number(null) === 0Number(undefined) === NaN// 类型typeof null === object typeof undefined === undefinedtypeof NaN === number 2. 布尔值 除了以下六个值为转换为false ,其他都视为true undefined null false 0 NaN ‘’ or “” 空对象和空数组对应为 true 3. 整数 & 浮点数 所有数值64位浮点数形式存储,故 1===1.0 底层都是小数存储,但某些运算只有整数才能完成,会自动把64浮点数转为32整数。 小数点前数字多于21位或者小数点后的零多于5个,则自动采用科学计数法3.1 进制,内部自动转化为十进制 0b 二进制 0o 八进制 0x 十六进制3.2 +0 & -0 唯一不同,+0 和 -0 当分母时,一个得到+Infinity,一个得到-Infinity3.3 NaN not a number typeof NaN => number NaN 不等于任何值 (NaN !== NaN) =>true Boolean(NaN) => false 与任何数运算都得到本身 Infinity 与 NaN 做比较,任何情况都返回 false 3.4 与数值相关的全局方法3.4.1 parseInt() 将第一个参数转化为字符串,根据第二个参数(2-36,默认为10)的进制转化为整数 每个字符依次转换,遇到不能转为数字的字符,不在进行,直接返回转好的部分,若整个字符串无法转换,返回NaN 对于自动转换为科学计数法的数字会直接对科学计数法当做字符串转换 1234parseInt('567',2);//NaNparseInt(0x10,16);// 结果为22不是16,因为0x10被自动转换为字符串String(0x10);// 16parseInt(0x10,16) => parseInt( String(0x10), 16 ) => parseInt(‘16’,16) 3.4.2 parseFloat() 将一个字符串转为浮点数,接受科学计数法 自动忽略前导零。 3.4.3 isNaN() 判断一个数值是否为NaN 只对数值有效,其他传入值自动转为数值123function myIsNaN( value ){ return value !== value;} 其他 string number(NAN) boolean undefined object(NULL) function symbol","categories":[{"name":"语言基础","slug":"语言基础","permalink":"http://yoursite.com/categories/语言基础/"}],"tags":[{"name":"-JS","slug":"JS","permalink":"http://yoursite.com/tags/JS/"}]},{"title":"Hello World","slug":"hello-world","date":"2019-05-22T12:55:46.832Z","updated":"2019-05-22T12:55:46.832Z","comments":true,"path":"2019/05/22/hello-world/","link":"","permalink":"http://yoursite.com/2019/05/22/hello-world/","excerpt":"","text":"Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new \"My New Post\" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment","categories":[],"tags":[]}]} \ No newline at end of file diff --git a/index.html b/index.html index ddbfcf3..ccbf205 100644 --- a/index.html +++ b/index.html @@ -25,7 +25,7 @@ @@ -801,19 +801,19 @@

1 -
+

- ECMA5 面向对象编程 + ECMA6 类

- @@ -821,17 +821,9 @@

-

1 实例对象与new 命令

1.1 构造函数

    -
  • 函数体内部使用了 this 关键字,代表了所要生成的对象实例。
  • -
  • 生成对象的时候,必须使用 new 命令
  • -
  • 函数名首字母大写,以示区别。
  • -
-

1.2 new 命令

    -
  • 执行构造函数,返回一个对象实例。
  • -
-

1.2.1 new 原理

1
2
3
4
graph TB
A[1.创建一个空对象作为将要返回的对象实例]--> B[2.将这个空对象的原型指向构造函数的prototype属性]
B-->C[3.将空对象赋值给函数内部的this关键字]
C-->D[4.开始执行构造函数内部的代码]
+

Classes

1 Class-Like structures in ecma5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// property
function PersonType(name){
this.name = name;
}

// methods: be assigned to the prototype
// all instances of the object share the same function
PersonType.prototype.sayName = function(){
console.log(this.name);
}

let person = new PersonType('chochi');
person.sayName();
// person is a instance of obeject and PersonType
- more >> + more >> @@ -866,7 +858,7 @@

- 展开全文 >> + 展开全文 >>

@@ -896,19 +888,19 @@

+

- ECMA6 类 + ECMA5 CALL APPLY 模拟

- @@ -916,9 +908,27 @@

-

Classes

1 Class-Like structures in ecma5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// property
function PersonType(name){
this.name = name;
}

// methods: be assigned to the prototype
// all instances of the object share the same function
PersonType.prototype.sayName = function(){
console.log(this.name);
}

let person = new PersonType('chochi');
person.sayName();
// person is a instance of obeject and PersonType
+

概念

    +
  • 每个函数都包括两个非继承而来的方法 apply call
  • +
  • 在特定的作用域中调用函数,实际上等于设置函数体内this对象的值
  • +
  • 看出 call 和 apply 是为了动态改变 this 而出现的

    区别

  • +
+
    +
  1. apply()
      +
    • 接受两个参数,第一个是运行函数的作用域,第二个是参数数组,参数数组可以用arrar实例,也可以是arguments对象。
    • +
    +
  2. +
  3. call()
      +
    • 参数必须逐个列出来
    • +
    +
  4. +
+

call 模拟

    +
  • 参数一一对应
  • +
+
1
2
3
4
5
6
7
8
Function.prototype.myCall = function(_context){
let context = _context || window;// null -> window
context.fn = this;
let args = [].slice.call(arguments,1,arguments.length);
let result = !args ?context.fn():context.fn(...args);
delete context.fn;
return result;
}
- more >> + more >> @@ -953,7 +963,7 @@

Class

- 展开全文 >> + 展开全文 >>

@@ -983,19 +993,19 @@

Class -
+

- ECMA5 CALL APPLY 模拟 + ECMA5 面向对象编程

- @@ -1003,27 +1013,17 @@

-

概念

    -
  • 每个函数都包括两个非继承而来的方法 apply call
  • -
  • 在特定的作用域中调用函数,实际上等于设置函数体内this对象的值
  • -
  • 看出 call 和 apply 是为了动态改变 this 而出现的

    区别

  • -
-
    -
  1. apply()
      -
    • 接受两个参数,第一个是运行函数的作用域,第二个是参数数组,参数数组可以用arrar实例,也可以是arguments对象。
    • -
    -
  2. -
  3. call()
      -
    • 参数必须逐个列出来
    • +

      1 实例对象与new 命令

      1.1 构造函数

        +
      • 函数体内部使用了 this 关键字,代表了所要生成的对象实例。
      • +
      • 生成对象的时候,必须使用 new 命令
      • +
      • 函数名首字母大写,以示区别。
      - -
-

call 模拟

    -
  • 参数一一对应
  • +

    1.2 new 命令

      +
    • 执行构造函数,返回一个对象实例。
    -
    1
    2
    3
    4
    5
    6
    7
    8
    Function.prototype.myCall = function(_context){
    let context = _context || window;// null -> window
    context.fn = this;
    let args = [].slice.call(arguments,1,arguments.length);
    let result = !args ?context.fn():context.fn(...args);
    delete context.fn;
    return result;
    }
    +

    1.2.1 new 原理

    1
    2
    3
    4
    graph TB
    A[1.创建一个空对象作为将要返回的对象实例]--> B[2.将这个空对象的原型指向构造函数的prototype属性]
    B-->C[3.将空对象赋值给函数内部的this关键字]
    C-->D[4.开始执行构造函数内部的代码]
    - more >> + more >> @@ -1058,7 +1058,7 @@

    - 展开全文 >> + 展开全文 >>

    diff --git a/page/2/index.html b/page/2/index.html index 1734cf6..b358667 100644 --- a/page/2/index.html +++ b/page/2/index.html @@ -25,7 +25,7 @@ diff --git a/showcase/showcase.html b/showcase/showcase.html index 64ea533..6a80042 100644 --- a/showcase/showcase.html +++ b/showcase/showcase.html @@ -29,7 +29,7 @@ diff --git a/showcase/works/Ajax/ajax.html b/showcase/works/Ajax/ajax.html index 05b8068..4b58427 100644 --- a/showcase/works/Ajax/ajax.html +++ b/showcase/works/Ajax/ajax.html @@ -29,7 +29,7 @@ diff --git a/showcase/works/Ajax/readme.html b/showcase/works/Ajax/readme.html index 78628d0..339e271 100644 --- a/showcase/works/Ajax/readme.html +++ b/showcase/works/Ajax/readme.html @@ -26,7 +26,7 @@ diff --git a/showcase/works/BallGame/BallGame.html b/showcase/works/BallGame/BallGame.html index 3683697..735c710 100644 --- a/showcase/works/BallGame/BallGame.html +++ b/showcase/works/BallGame/BallGame.html @@ -32,7 +32,7 @@ diff --git a/showcase/works/IamgeSlider/IamgeSlider.html b/showcase/works/IamgeSlider/IamgeSlider.html index f1ac3e6..fdfbf6a 100644 --- a/showcase/works/IamgeSlider/IamgeSlider.html +++ b/showcase/works/IamgeSlider/IamgeSlider.html @@ -39,7 +39,7 @@ diff --git a/showcase/works/flex/flex.html b/showcase/works/flex/flex.html index 54dbc4d..6f9a620 100644 --- a/showcase/works/flex/flex.html +++ b/showcase/works/flex/flex.html @@ -29,7 +29,7 @@ diff --git a/showcase/works/flex/readme.html b/showcase/works/flex/readme.html index 3372597..f75ce60 100644 --- a/showcase/works/flex/readme.html +++ b/showcase/works/flex/readme.html @@ -29,7 +29,7 @@ diff --git a/tags/JS/index.html b/tags/JS/index.html index 9d7ac1e..777a9cb 100644 --- a/tags/JS/index.html +++ b/tags/JS/index.html @@ -25,7 +25,7 @@ @@ -498,14 +498,14 @@

    - ECMA5 面向对象编程 + ECMA6 类

    @@ -547,14 +547,14 @@

    - ECMA6 类 + ECMA5 CALL APPLY 模拟

    @@ -596,14 +596,14 @@

    - ECMA5 CALL APPLY 模拟 + ECMA5 面向对象编程

    diff --git a/tags/JS/page/2/index.html b/tags/JS/page/2/index.html index 2c46e48..d7c4a15 100644 --- a/tags/JS/page/2/index.html +++ b/tags/JS/page/2/index.html @@ -25,7 +25,7 @@