js_(二)
1. for循环的一些细节
var i = 1;
var sum = 0;
while(i <= 100){
sum += i;
i++;
}
console.log(sum);
2. 函数的认识
函数是是具有特定功能的代码
- 避免代码重复
- 方便管理和维护,便于复用
- 有利于程序维护和开发效率。
2.1 - 使用函数的步骤
- 先声明函数(定义函数)
- 调用函数
- 形参在函数内部就当作一个普通的变量来使用。
2.2 - 输出范围内的所有的整数的和。
function add(from, to) {
var sum = 0;
for(var i=from; i<=to; i++){
sum += i;
}
console.log(sum);
}
add(10, 100);
2.3 - 一个数,计算是否为质数
function number(num) {
var flag = true;
for(var j=2, v=Math.sqrt(num); j<=v; j++){
if(num % j == 0){
flag = false;
break;
}
}
if(flag){
console.log(num + "是质数");
}else {
console.log(num + "是合数");
}
}
var num = prompt("shuru");
number(num);
3. 函数的返回值
-
函数三要素
- 函数名
- 动词多一些
- 驼峰命名,不能数字开头
- 见名知意(做不到就加注释)
- 形参
- 形参如何定义
- 需要与否,需要多少。
- 返回值
- 函数返回给调用者的函数计算出来的结果。
- 函数名
- 在函数内部使用return来把数据返回给函数的调用者
- 两个作用:
- 给调用者返回值;
- 只要在函数内部碰到return,则立即把返回值给调用者,同时会立即结束函数的执行。
3.1 - 一个数,计算是否为质数
/**
* 判断一个指定的数是否为质数
* @param num 就是指定的要判断的那个整数
* @return 如果传入的数是质数,则返回true,否则返回false
*/
function isPrime(num){
for(var i=2; i<num; i++){
if(num % i == 0){
return false;
}
}
return true;
}
var n = 6;
if(isPrime(n)){
console.log(n + "是质数");
}else {
console.log(n + "是合数");
}
3.2 - 求质数和
function isPrime(num){
for(var i=2; i<num; i++){
if(num % i == 0){
return false;
}
}
return true;
}
function sumPrimes(from, to) {
var sum = 0;
for(var i=from; i<=to; i++){
if(isPrime(i)){
sum += i;
}
}
return sum;
}
function sumHeshu(from, to) {
var sum = 0;
for(var i=from; i<=to; i++){
if(!isPrime(i)){
sum += i;
}
}
return sum;
}
console.log(sumPrimes(1, 100));
console.log(sumHeshu(1, 100));
//---------------------------------
// function sumPrimes(from, to) {
// var sum = 0;
// for(var i=from; i<=to; i++){
// var flag = true;
// for(var j=2; j<i; j++){
// if(i % j == 0){
// flag = false;
// break;
// }
// }
// if(flag){
// sum += i;
// }
// }
// return sum;
// }
3.3 - 阶乘和
function Jc(num){
var plus = 1;
for(var i=num; i>0; i--){
plus *= i;
}
return plus;
}
function JcAdd(from, to){
var sum = 0;
for(var i=from; i<=to; i++){
sum += Jc(i);
}
return sum;
}
console.log(JcAdd(1, 10));
//--------------------------------
function jcAdd(from, to){
var sum =0;
var plus = 1;
for(var i=from; i<=to; i++){
plus *= i;
sum += plus;
}
return sum;
}
console.log(jcAdd(1, 10));
4. 关于函数的返回值数方面的一些细节
- 函数没有return,一直运行到函数的最后一行代码。
- 默认返回值是undefined.
- return后面可以不跟任何数据。这个时候返回值也为undefined。
- 这个时候其实是为了让函数立即结束
5. 匿名函数
- 如果一个变量,给它赋一个函数,它就叫做函数表达式。
var foo = function () {
console.log(a);
};
console.log(foo);
foo();
- 匿名函数的作用:
- 给变量赋值,成为函数表达式,那么这个变量就当作一个正常的函数来使用。
- 封装私有数据
- 配合函数的自调用/自执行
- 作为参数传递,和作为返回值返回。(高阶函数)
(function () {
console.log("a");
}) ();
//----------------写法意义是相通的。
(function () {
console.log("a");
}());
6. 函数的递归调用
函数自己调用自己
- 一定要有两个条件:
- 一定要有递归结束的条件
- 随着递归的深入,一定要能达到这个结束的条件
function jiecheng(n) {
if(n == 1) return 1;
return n * jiecheng(n - 1);
}
console.log(jiecheng(5));
7. 原型
- JS中一切皆对象
- 只要是对象,都可以有自己的属性
- 作为一个函数对象,也会有自己的属性
- 当完成一个函数声明之后,JS引擎会自动的创建一个对象,这个对象表示函数对象
- 函数对象会有一个属性prototype,他指向一个对象,这个对象也是自动创建出来的。这个对象就是函数的原型对象。
- 原型对象也有一个属性constructor,表示构造器,他会指向函数对象
- 任何的函数都会有原型对象,只是我们只关注和研究构造函数的原型对象,普通函数的原型对象我们不关注
function Person(){
}
console.log(Person.prototype);
console.log(Person.prototype.constructor === Person);
function Father() {
this.name = 'eloise'
}
Father.prototype.giveMoney = function () {
console.log('im eloise, hello');
}
function Son() {
this.age = '2222'
}
Son.prototype = new Father();
var s = new Son();
console.log(s.age);
console.log(s.name);
s.giveMoney()
8. 动态原型
function Person(name, age){
this.name = name;
this.age = age;
// if(Person.prototype.speak != "function"){
if(!Person.prototype.speak){
Person.prototype.speak = function(){
return this.name + "say:hi";
};
Person.prototype.smile = function(){
return this.age + "smile";
};
Person.prototype.kneel = function(){
return this.name + this.age + "lalala";
}
}
}
- 初次运行的时候,Person.prototype.speak为false,取反为true,进入循环。
- 第二次运行的时候,Person.prototype.speak已有方法,可以通过内容访问到,因此不会进入到if方法中,避免原型方法的重复定义
- 如果去掉if的话,你每new一次(即每当一个实例对象生产时),都会重新定义一个新的函数,然后挂到Person.prototype.speak属性上。而实际上,你只需要定义一次就够了,因为所有实例都会共享此属性的。所以如果去掉if的话,会造成没必要的时间和空间浪费;而加上if后,只在new第一个实例时才会定义speak方法,之后就不会了。
9. 原型替换法
9.1 - 方法一
function Person(name){
this.name = name;
}
Person.prototype = {
constructor : Person,
speak: function(){
console.log(this.name + "say:hi·");
},
};
var p1 = new Person("李四");
p1.speak();
9.2 - 方法二
function Person(name, age){
this._init(name, age);
}
Person.prototype = {
_init : function(name, age){
this.name = name;
this.age = age;
}
constructor : Person,
speak: function(){
console.log(this.name + "say:hi·");
},
say: function(){
},
};
var p1 = new Person("李四");
p1.speak();
9.3 - 方法三(无敌)
function Person(opt){
this._init(opt);
}
Person.prototype = {
_init : function(opt){
// this.name = opt.name;
// this.age = opt.age;
Object.assign(this, opt);
}
constructor : Person,
speak: function(){
console.log(this.name + "say:hi·");
},
say: function(){
},
};
var p1 = new Person({name:"lisi", age:22});
p1.speak();
10. 与原型相关的几个属性和方法
- 构造函数有一个属性prototype,指向原型对象
- new出来的对象会有一个不可见的属性[[proto]],指向函数的原型对象
- 游览器私自实现了一种方式去访问这个不可见的属性
属性名.__proto__
function Person(){
}
var p1 = new Person();
console.log(p1.__proto__);
console.log(Person.prototype === p1.__proto__);
-
in 操作符
- 用来查找属性是否在这个对象上存在,
- 先在当前对象找,找不到就去原型上去找
function Person(){ this.name = "eloise"; } Person.prototype.age = 10; var p1 = new Person(); console.log("name" in p1); //true console.log("age" in p1); //true console.log("sex" in p1); //false
-
hasOwnProperty
- 只在自己身上找,不在原型上找。
function Person(){ this.name = "eloise"; } Person.prototype.age = 10; var p1 = new Person(); console.log(p1.hasOwnProperty("name")); //true console.log(p1.hasOwnProperty("age")); //false console.log(p1.hasOwnProperty("sex")); //false
11. 对象的判断
- 如果两个对象比较相等。= = =/= =,都是比较内存地址
- 如果一端是基本类型,一端是对象
- === 肯定是false
- == 会先变成基本类型,然后再用基本类型的规则进行比较
- 先调用这个对象的valueof方法,如果返回的是基本类型数据,则用这个基本类型的数据进行比较,默认valueof返回的是对象自己。
- 如果返回的是对象,然后使用toString()方法,默认返回的是这样的一个字符串
"[object Object]"
var a = { age : 10, valueOf : function(){ return 0; } // toString : function(){ // return 1; // } }; var b = {}; console.log(a == ""); //true console.log(a == "[object Object]"); //true console.log(b == "[object Object]"); //true
网友评论