//1做一個循環,計算累加到300需要的次數---------------------------------------------------------
// var num = 1;
// var times = 0;
//1
// var realdo = true;
// for (var i = 1; realdo; i++) {
// num += i;
// times++;
// // num > 300 && console.log(times);
// if (num > 300) {
// console.log(times);
// realdo = false;
// }
// }
//2
//for (var i = 1; i < 1000; i = i + 1) {
// num += i;
// times++;
// if (num > 300) {
// console.log(times);
// i = 1000;
// }
// }
//3
// for (var i = 1; num <= 300; i++) {
// num += i;
// times++;
// }
// console.log(times);
// 4
for (; num <= 300;) { // -------- num 小於等於 300 嗎? 是,執行下面語句 不是跳出循環 結果爲循環後的值
num += ++times;
}
console.log(times);
// 5
while (num <= 300) {
num += ++times; //++times:0,1,2,3,4
// num 是累加的和 去加上 調節數++times
}
//2求2的n次方--------------------------------------------------------------------------------
var n = parseInt(window.prompt());
var num = 2;
if (n == 0) {
console.log(1);
}
// else if (n == 1) { console.log(2);}
else {
for (var i = 0; i < n - 1; i++) {
num *= 2;
}
console.log(num);
}
// for (var i = 0; i < 99;) {} // 99次循環
// for (var i = 1; i <= 99;) {} // 99次循環
//3階乘-----------------------------------------------------------------------------------------
//方法1
var a = parseInt(window.prompt());
var num = 1;
if (a == 0 || a == 1) console.log(1);
else {
for (var i = 1; i <= a; i++) {
num *= i;
}
console.log(num);
}
//方法2
// var num = a;
// for (var i = a - 1; i > 0; i--) {
// num = num * i;
// }
// console.log(num);
//4斐波那契數列-----------------------------------------------------------------------------
var n = parseInt(window.prompt());
// 1 1 2 3 5 8 13 21
// f s
// l=f+s
// f s
// l
// f s
// l
var f = 1;
var s = 1;
var last = 0;
if (n == 1 || n == 2) console.log(1);
else {
for (var i = 0; i < n - 2; i++) { // 做循環次數,不影響循環體內容,我只負責循環幾次
last = f + s;
f = s; // 後一位的值賦值給前一位, s --> f
s = last; // l --> s
}
console.log(last);
}
//5輸入三個數,輸出最大值-------------------------------------------------------------------------------
// var a = parseInt(window.prompt());
// var b = parseInt(window.prompt());
// var c = parseInt(window.prompt());
// var max = a;
// if (max < b) max = b;
// if (max < c) max = c;
// console.log(max);
var max = 0;
for (var i = 0; i < 5; i++) {
var currValue = parseInt(window.prompt());
if (max < currValue) {
max = currValue;
}
}
console.log(max);
//6輸入一組數字,反向輸出-------------------------------------------------------------------------------
var num = parseInt(window.prompt());
var g, s, b;
g = num % 10;
s = (num - g) / 10 % 10;
b = (num - g - s * 10) / 100;
num = g * 100 + s * 10 + b;
console.log(num);
//7輸出100以內的質數------------------------------------------------------------------------------------
var count = 0;
for (var i = 1; i <= 100; i++) { // 把1-100個拿出來
for (var j = 1; j <= i; j++) { // 每拿出來一個數就對應的計算
if (i % j == 0) {
count++;
}
}
if (count == 2) {
console.log(i); //當循環結束後,計數器爲2表示質數
}
count = 0; // 輪到下一個數計數器清零
}
//8 break語句練習---------------------------------------------------------------------------------------
for (var i = 0; i < 100; i++) {
for (var j = 0; j < 100; j++) {
console.log(j);
if (j == 10) {
break;
}
}
}
//9 contintue語句練習---------------------------------------------------------------------------------
for (var i = 0; i < 100; i++) {
if (i % 5 == 0) {
continue;
}
console.log(i);
}
//10 死循環-------------------------------------------------------------------------------------------
var times = 0;
while (true) {
times++;
var num = Math.floor(Math.random() * 100);
if (num == 33) {
break;
}
}
console.log(times);
// 隨機生成數字符合 11 * i 需要的次數
for (var i = 1; i < 10; i++) {
var times = 0;
var selfNum = 11 * i;
while (true) {
times++;
var num = Math.floor(Math.random() * 100);
if (num == selfNum) {
break;
}
}
console.log(selfNum + ':' + times);
}
//11 單純拼接代碼------------------------------------------------------------------------------------------
var person = {
name: 'nike',
age: 18
}
var property = 'age';
console.log(person['property']);
console.log(person[property]);
// 沒有任何意義,單純的字符串拼接,像一個拼圖,property就是 'age'
// 而兩者的區別是,第一個訪問失敗,因爲對象裏沒有'property'屬性
// 而第二句,就是person['age']
//property = 'age' person[property] = person['age']
//12 把八進制30427轉換成二進制------------------------------------------------------------------------------
var a = parseInt(30427, 8); // 8 -> 10
var b = a.toString(2); // 10 -> 2
//13 遞歸求函數階乘-----------------------------------------------------------------------------------------
// 遞歸 1找規律 2找出口
// 10! = 10*9!
// n * (n-1)!
// ft(n) = n * ft(n - 1);
function ft(n) {
if (n >= 0) {
n = parseInt(n);
if (n == 0 || n == 1) {
return 1;
}
return n * ft(n - 1);
// 5 * ft(4)
// 4 * ft(3)
// 3 * ft(2)
// 2 * ft(1)
} else {
return 'false';
}
}
//14 遞歸求斐波那契數列(盡力避免使用遞歸)--------------------------------------------------------------------------------
// 1 1 2 3 5 8 13 21
// 1 2 3 4 5 6 7 8
// 6
// 5 + 4
// 4 + 3 3 + 2
// 3 + 2 2 + 1 2 + 1
function ft(n) {
if (n == 1 || n == 2) { return 1 };
return ft(n - 1) + ft(n - 2);
// ft(4) + ft(3)
// ft(3) + ft (2) ft(2) + ft(1)
// ft(2) + ft(1) + ft(2) + ft(2) + ft(1)
}
//15 有100個臺階,每次可以走一步或兩步,問走完有多少種情況?-----------------------------------------------------
function stair(n) {
if (n <= 0) { return 0 };
if (n == 1) { return 1 };
if (n == 2) { return 2 };
return stair(n - 1) + stair(n - 2);
}
console.log('走完100個臺階有:' + stair(10) + '情況');
// 問題本質上是斐波那契數列,假設只有一個臺階,那麼只有一種跳法,那就是一次跳一級,f(1)=1;
// 如果有兩個臺階,那麼有兩種跳法,第一種跳法是一次跳一級,第二種跳法是一次跳兩級,f(2)=2。
// 如果有大於2級的n級臺階,那麼假如第一次跳一級臺階,剩下還有n-1級臺階,
// 有f(n-1)種跳法,假如第一次條2級臺階,剩下n-2級臺階,有f(n-2)種跳法。
// 這就表示f(n)=f(n-1)+f(n-2)。
//16 作用域鏈----------------------------------------------------------------------------------------------
var global = 300;
function test() {
console.log(global); // AO: undefined
var global = 400;
console.log(global); // 400
}
test();
//-----------------------------------
var global = 100;
function test() {
console.log(global); // AO :沒有global GO:100
global = 200; //不是變量聲明
console.log(global); // 200
}
test();
console.log(global); // 200
//----------------------------------
show();
var a;
a = 234;
function show() {
console.log(b); // undefined
if (a) {
var b = 10; // 是否考慮前面的條件語句,還是隻要引擎看到var就提升
}
console.log(b); // undefined
}
// ---------------------------------
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = 11;
}
console.log(bar()); // 11
function bar() {
foo = 10;
function foo() {}
var foo = 11;
return foo;
}
console.log(bar()); // 11
//17 閉包--------------------------------------------------------------------------------
function a() {
function b() {
var bbb = 234;
document.write(aaa);
}
var aaa = 123;
return b;
}
var glob = 100;
var demo = a();
demo();
//--------------------
function add() {
var num = 0;
function get() {
num++;
console.log(num);
}
return get; //-----
} // ------get函數被保存到外部,它的作用域鏈scope chain -> {0:getAO,1:addAO,2:GO}
var outerGet = add(); // ----
outerGet(); // 1
outerGet(); // 2
outerGet(); // 3 一直操作的是作用域鏈當中的num值,即 接着上一次的num運算結果
// 每次執行,使用的都是同一個AO, AO沒有被銷燬
//----------------------------------
function add() {
var num = 0;
num++;
console.log(num);
}
add(); // 每次執行會創建一個新的AO
add();
add();
//18閉包------------------------------------------------------------------------------------------------
function eater() { // GO -> {}
var food = ''; // 位置1存檔1:eaterAO -> {food :'orange',obj:object,}
// 位置2存檔1:eaterAO -> {food :'',}
var obj = {
eat: function() {
console.log('i am eating ' + food) // eatAO/pushAO -> { myFood:orange }
},
push: function(myFood) {
food = myFood;
}
}
return obj;
}
var eater1 = eater(); //存檔(存位置1),讀檔
eater1.push('orange'); //買了一件新裝備
eater1.eat(); //賣了一件新裝備
var eater2 = eater(); //存檔(存位置2),讀檔
eater2.eat(); //所以在此運行,輸出空串
//19閉包,立即執行函數------------------------------------------------------------------------------------------
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function() {
console.log(i); // i在GO中
}
}
a[0](); // 10
a[1](); // 10
//--------------------------------
var a = []; //定義了一個數組,每次循環都會向數組各索引存儲一個輸出函數
for (var i = 0; i < 10; i++) {
(function(i) { // [[scope]] -> {0:nAO -> {i:0} 1:GO -> {}} 保存到外部,形成閉包,存檔
a[i] = function() { // a[i].[[scope]] -> {0:a[i]AO,1:nAO,2:GO} a[i]AO每次執行完銷燬
console.log(i);
}
// return 因爲將函數存到了全局的數組當中,相當於將函數return到外部
})(i);
}
a[1](); // 產生閉包,立即執行函數不會被銷燬,相當於普通函數
a[9](); // 每一次循環,將i=1~9傳入函數
//20 臨時對象 包裝類-----------------------------------------------------------------------------------------
var str = 'cst';
str.name = 'ccc';
console.log(str.name + 'aaa'); // undefinedaaa
//21 包裝類--------------------------------------------------------------------------------------------------
function check(str) {
// adsf哈哈
var count = 0;
for (var i = 0; i < str.length; i++) {
var a = str.charCodeAt(i);
console.log(a);
if (a < 255) {
count += 1;
} else {
count += 2;
}
}
return count;
}
//22 原型---------------------------------------------------------------------------------------------------
Person.prototype.name = 'sunny';
function Person() {}
var oPerson = new Person();
Person.prototype.name = 'cherry';
console.log(oPerson.name); // cherry
//======================================
Person.prototype.name = 'sunny';
function Person() {}
Person.prototype.name = 'cherry';
var oPerson = new Person();
console.log(oPerson.name); // cherry
//======================================
Person.prototype.name = 'sunny';
function Person() {}
var oPerson = new Person();
Person.prototype = {
name: 'cherry'
};
console.log(oPerson.name); // sunny
//=======================================
Person.prototype.name = 'sunny';
function Person() {}
Person.prototype = {
name: 'cherry'
};
var oPerson = new Person();
console.log(oPerson.name); // cherry
//23 原型鏈-------------------------------------------------------------------------------------------------
GrandFather.prototype.lastName = 'yang';
function GrandFather() {
this.bike = 1;
}
Father.prototype = new GrandFather();
function Father() {
this.fortune = {
money: 999999,
house: 4
}
this.name = 'jaja'
}
Son.prototype = new Father();
function Son() {
this.name = 'heihei',
this.age = 20
}
var oSon = new Son();
console.log(oSon.lastName);
oSon.fortune.house += 1; //訪問fortune對象的屬性並賦值,改變相同地址的引用值, 相當於改變原型上的屬性
oSon.fortune = {}; //將fortune屬性指向另一個對象地址,換了一個引用值, 相當於給oSon自己添加屬性
var oSon2 = new Son();
console.log(oSon2.fortune.house); // 5 這個是引用值,後續會受影響
//24 call apply----------------------------------------------------------------------------------------------
function Person(name, age) {
this.name = name;
this.age = age;
}
function Student(name, age, myClass, myGrade) {
Person.call(this, name, age); // Studnet函數調用Person函數,保證Person函數的參數
} // call(name,age)->Student(name,age)->Student(實參)
// this是當前調用的函數Student
new Student('cst', 18, 2, 4); //構造函數會在內部隠式創建this對象並返回,
//原因是構造函數本身就是用於創建對象並初始化
//構造函數身份象徵:new
var numObj = {
x: 1,
y: 2
}
function add(a, b) {
console.log(this.x + a + this.y + b);
}
add(); // NaN
add.call(numObj, 3, 4); // 10
//25聖盃繼承-----------------------------------------------------------------------------------------------------
var inherit = (function() {
var Cache = function() {}; //緩存函數,每次執行都需要創建一個,沒有必要,寫入閉包
return function(Target, Origin) {
Cache.prototype = Origin.prototype; //下游不影響上游
Target.prototype = new Cache();
Target.prototype.constructor = Target; // 手動更改構造函數
Target.prototype.uber = Origin;
}
})();
// 立即執行函數執行完成後返回一個函數,賦值給inherit.由於函數被保留到外部,形成閉包。
// 相當於我把新建緩存的函數存儲到了執行期上下文裏,隨手就用
//26屬性訪問-----------------------------------------------------------------------------------------------------
var obj = {
number1: haha,
number2: lala,
roc: function(num) {
document.writes('這個數字是' + this['number' + num]);
}
}
//==============================
var person = {
name: 'nike',
age: 18
}
var property = 'age';
person['property'];
person[property];
// 沒有任何意義,單純的字符串拼接,像一個拼圖,property就是 'age'
// 而兩者的區別是,第一個訪問失敗,因爲對象裏沒有'property'屬性
// 而第二句,就是person['age']
//==============================
var o = { x: 1, y: 2, z: 3 };
o.propertyIsEnumerable('toString');
for (p in o)
console.log(p, o[p], o.hasOwnProperty(p));
//27 this-----------------------------------------------------------------------------------------------------
var name = '222';
var a = {
name: '111',
say: function() {
console.log(this.name);
}
}
var b = {
name: '333',
say: function(fun) {
fun();
// a.say();
// function(){console.log(this.name}} 相當於沒有對象顯式調用,this是window
}
}
a.say(); //111
b.say(a.say); //222 把函數a.say當做參數傳入,傳入後執行
b.say = a.say;
b.say(); //333 把東西更改,但是執行上下文根據所在環境
//-------
var foo = '123';
function print() {
this.foo = '234';
console.log(foo);
};
print(); //234
new print(); //123 AO{this:{foo}} 構造函數創建this對象,相當於foo是對象內部屬性,平行關係,無法訪問foo
//28 clone--------------------------------------------------------------------------------------------------
var mrChen = {
name: 'cst',
age: 18,
sex: 'man',
height: 183,
girl: {
name: 'zly',
age: 28,
house: {
name: 'ai'
}
}
}
var obj = {};
function clone(target, origin) {
for (var prop in origin) {
target[prop] = origin[prop];
}
}
clone(obj, mrChen);
//淺層克隆,有引用值就不好用了
function clone(target, origin) {
var str = '[object Array]'; //數組身份
var toString = Object.prototype.toString; //對象方法toString
for (var prop in origin) {
if (origin.hasOwnProperty(prop)) {
if (origin[prop] == target) { //防止循環引用,判斷如果對象的屬性值是目標函數,跳過此次循環
continue;
}
if (typeof origin[prop] == 'object') {
if (toString.call(origin[prop]) === str) { // 判斷數組
target[prop] = []; // 讓這個值等於一個新數組
} else {
target[prop] = {};
}
clone(target[prop], origin[prop]); //剝開數組和對象,循環引用函數本身
} else {
target[prop] = origin[prop];
}
}
}
}
//深層克隆 遞歸 注意防止循環引用
var obj = {};
var obj2 = {
name: obj
}
obj.name = obj2.name;
if (origin[prop] == target);
continue;
//純函數 pure function :函數執行後對外界不會有任何影響(引用值的事)
//當函數操作引用值時,可能會對其值改變,保證函數是純函數,可以創建新引用值並返回或使用深度克隆
//說白了,無論是垂直的繼承還是水平的克隆,都是因爲引用值的原因。聖盃繼承和深度克隆。這兩種方式提供純函數
//29 test() 和 new test()--------------------------------------------------------------------------------------
var a = 5;
function test() { // AO {a:undefind -> 0} GO {this:window}
//AO{a:0}
a = 0; // 關鍵,在以test()方式執行時,是賦值給AO.a
alert(a); // 0
alert(this.a); // window.this.a -> 5
var a;
alert(a); // 0
}
test()
function test() {
// var this = {}
a = 0;
alert(a); //0
//this.a = a
alert(this.a); // undefined a有值,但是this裏沒有a屬性 ,不會想當然的的賦值
var a;
alert(a); //0
// return this
}
new test()
//30 構造函數執行-----------------------------------------------------------------------------------------------
function employee(name, code) {
this.name = 'wangli';
this.code = 'A001';
}
newemp = new employee('zhangming', 'A002');
document.write('僱員姓名:' + newemp.name + ' <br> '); // wangli
document.write('僱員代號:' + newemp.code + ' <br> ') //A001
//31 函數執行-------------------------------------------------------------------------------------------------
function test(a) {
// AO{a:undefined,b:undefined,c:undefined}
// AO{a:44,b:undefined,c:function,this:window}
console.log(this); //window
var b = 10;
function c() {
}
var c = 20;
}
test(44); // window.test.call(window,44)
//----普通函數----
var obj = {
name: 'hah',
show: function test() {}
//{this:obj}
}
obj.test(44) //obj.test.call(obj,44)
//----方法調用----
new test(); // Object.create(test.prototype).test.call(Object.create(test.prototype))
// 高能! var this = Object.create(test.prototype); 就是創建一個新對象和原型
//----構造函數----
// call & apply 可以改變this指向
//32 bind()---------------------------------------------------------------------------------------------------
//1.創建綁定函數
this.a = 1;
var module = {
a: 2,
getA: function() {
return this.a;
}
};
console.log(module.getA()); //2
var getA1 = module.getA;
// getA在外部調用,此時的this指向了全局對象
console.log(getA1()); //1
// 再把getA1方法綁定到module環境上
var getA2 = getA1.bind(module);
console.log(getA2()); //2
// 將函數綁定到指定對象上 func.bind(obj); func.bind(this,arg1,arg2);
//bind()方法創建一個新的函數,叫做綁定函數,這個方法會在this的環境下執行
//當我們調用某些方法要在特定的環境下才能調用到,就是使用bind把函數綁定到特定的所需的環境下
//2.讓函數擁有預設的參數
function list() {
// 讓類數組arguments擁有數組的方法slice,這個函數實現了簡單把類數組轉換成數組
return Array.prototype.slice.call(arguments);
}
list(1, 2, 3); //[1,2,3]
//給list綁定一個預設參數4
var list1 = list.bind(undefined, 4);
list1(); //[4]
list1(1, 2, 3); //[4,1,2,3]
//33 作用域------------------------------------------------------------------------------------------------
var bar = { a: '002' };
function print() {
bar.a = 'a';
Object.prototype.b = 'b';
return function inner() {
console.log(bar.a);
console.log(bar.b);
}
}
print()();
//34 逗號運算符-------------------------------------------------------------------------------------------
var num = (1, 2);
console.log(num); //2
var f = (function h() { return '1' }, function g() { return 2 })();
console.log(typeof f);
//返回後面的值
//35 括號可以把一個函數變成表達式
var x = 1;
if (function f() {}) { //判斷布爾值,函數是對象,不是空對象都是真值,這裏相當於一個立即執行函數,判斷完銷燬
x += typeof f;
}
console.log(x); // 1undefined
//36 arr.push()、pop()、unShift()、shift()實現-----------------------------------------------------------------------------------------
var arr = [1, 2, , , 3];
// arr.push(2, 3, 4, 5);
Array.prototype.myPush = function() {
for (var i = 0; i < arguments.length; i++) { //0-4
this[this.length] = arguments[i] //數組的最後一位等於實參列表的第一位
}
return this.length;
}
//arr.myPush(1, 2, 3, 4, 'ig');
Array.prototype.myPop = function() {
var val = this[this.length - 1]; // 數組的最後一位
this.length -= 1; // 干預數組長度,使其自動截斷
return val; // 返回val
}
var arr = [1, 2, 3];
Array.prototype.myUnshift = function() {
var a = [];
var b = arguments.length;
// console.log(b); 2
var c = this.length;
// console.log(c); 3
for (var i = 0; i < b; i++) {
a[i] = arguments[i];
}
for (var j = 0; j < c; j++) {
a[b + j] = this[j];
}
// console.log(a);
for (var k = 0; k < b + c; k++) {
this[k] = a[k];
}
return this.length;
}
// arr.myUnshift(9, 8); // [9,8,1,2,3]
Array.prototype.myShift = function() {
// [1,2,3] -> [2,3] return 1
var val = this[0];
var b = [];
for (var i = 0; i < this.length - 1; i++) {
b[i] = this[i + 1];
// console.log(b);
}
for (var j = 0; j < b.length; j++) {
this[j] = b[j];
this.length = b.length;
// console.log(this)
}
return val;
}
//37 類數組------------------------------------------------------------------------------------------------------
//1 屬性名是連續數字
//2 有length屬性
//3 必須有push方法和splice方法
var obj = {
//[ , ,'a','b']
2: 'a',
3: 'b',
length: 2, //長度是2 ,push源碼是利用this[this.length] = arguments[length]
push: Array.prototype.push,
splice: Array.prototype.splice
}
obj.push('c');
obj.push('d');
console.log(obj); // [undefined,undefined,'c','d']
//38 數組去重----------------------------------------------------------------------------------------------------
var arr = [10, 8, 9, 2, 8, 9, 10, 1, 2, 3, 1, 2, 2, 9, 9, 10, 3, 5, 5];
Array.prototype.unique = function() {
var obj = {};
var newArr = [];
for (var i = 0; i < this.length; i++) {
if (!obj[this[i]]) { // 把數組裏的值當做對象的屬性名,第一次出現對象當中沒有這個屬性,取非進入循環
newArr.push(this[i]); //把這個進入循環的數推入新數組
obj[this[i]] = true; // 做標記,再出現時無法進入循環
}
}
return newArr;
}
var newArr = arr.unique();
//39 try catch------------------------------------------------------------------------------------------------
//錯誤類型 ReferenceError 使用一個變量,變量還沒有沒定義聲明
// RangeError 數值越界,遞歸沒有出口
// SyntaxError 語法解析錯誤 多寫少寫括號
// TypeError 類型錯誤 類型調用本身沒有的動作
try {
console.log(a);
a = 10;
} catch (e) {
console.log(e);
//ReferenceError: a is not defined
//at test.html:15
console.log(e.name, e.message);
//ReferenceError a is not defined
} finally {
console.log('over');
}
實例練習
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.