欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

实例练习

程序员文章站 2024-03-19 22:57:40
...
//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');
}






相关标签: 实例