Freecodecamp。

在我们深入 面向对象编程之前 ,让我们先回顾一下Javascript的 对象(Object) 

任务:给你的 motorBike 对象添加 wheels, engines seats 属性,并且设置他们的数量。

var car = {

  "wheels":4,

  "engines":1,

  "seats":5

};



除了上一种方法外,我们还可以使用构造函数来创建对象。

 构造函数 通常使用大写字母开头,以便把自己和其他普通函数区别开。

下面便是一个 构造函数 了:

var Car = function() {

  this.wheels = 4;

  this.engines = 1;

  this.seats = 1;

};

在  构造函数  中, this 指向被此 构造函数 创建出来的 对象 。所以,当我们在 构造函数 中写:

  this.wheels = 4;

这时,它创建出来的新对象将带有 wheels 属性,并且赋值为 4.

你可以认为 构造函数 描述了它所创建出来的对象

让你的 MotorBike 构造函数 描述一个具有 wheels, enginesseats 属性的 对象 ,并且为这些属性设置值。



现在,我们把上一节课我们写的 构造函数 在这里用起来!

使用构造函数时,我们通过在它前面使用 new 关键字 来对它进行调用,如下:

var myCar = new Car();

myCar 现在成为了 Car 的一个 实例(instance),它被 构造函数 描述成下面的样子:

{

  wheels: 4,

  engines: 1,

  seats: 1

}

记住:要使用 new 关键字 去调用构造函数。因为只有这样,Javascript才知道这是要去构造一个新 对象 ,并且把构造函数中的 this 指向这个新对象。

现在,当 myCar (即 Car 的一个 实例 )创建后,他可以像普通对象一样被使用,包括创建、访问、修改它的属性等,就像我们使用其他对象一样。如下:

myCar.turboType = "twin";

我们的 myCar 变量现在有了一个 turboType 属性了,且值为 "twin"

在编辑器中,使用 Car 这个构造函数去创建一个新的 实例 ,并且把这个实例赋值给 myCar

然后给 myCar 创建一个 nickname 属性,且属性值为一个字符串。



我们之前写的 构造函数 很好,但是我们不想总是创建相同的对象,怎么办呢?

为了解决这个问题,我们要向 构造函数 中添加 参数 。像下面这样:

var Car = function(wheels, seats, engines) {

  this.wheels = wheels;

  this.seats = seats;

  this.engines = engines;

};

现在,我们可以在调用 构造函数 时传入一组 参数 了。

var myCar = new Car(6, 3, 1);

这段代码将会使用这一组 参数 来创建出下面的对象:

{

  wheels: 6,

  seats: 3,

  engines: 1

}

现在该你试试了!改动 Car构造函数 ,使它能够通过使用 参数 来为 wheelsseatsengines 属性进行赋值。

然后调用你刚刚改写过的 构造函数 ,并传入三个 参数 ,我们就能看到创建的新对象赋值给了 myCar



对象拥有自己的特征,称为 属性,对象还有自己的函数,称为 方法

在前面的课程(构造函数)中,我们使用了 this 指向当前(将要被创建的)对象中的 公有属性

我们也可以创建 私有属性私有方法 ,它们两个在对象外部是不可访问的。

为了完成这个任务,我们在 构造函数 中,使用我们熟悉的 var 关键字去创建变量,来替代我们使用 this 创建 属性

比如,我们想记录我们的car行驶的 speed ,但是我们希望外面的代码对 speed 的修改只能是加速或减速(而不是变成字符串、直接赋值成某个速度等其他操作),那么如何达到这类操作的目的呢?

编辑器中的 构造函数 展示了如何实现这种控制模式。

该你自己试试了!修改 Bike构造函数 ,使它有一个名为 gear私有属性 ,还有两个公有方法,叫做 getGearsetGear ,这两个方法用来获得和设置 gear 的值。

var Car = function() {

  // this is a private variable


  var speed = 10;

  // these are public methods

  this.accelerate = function(change) {

    speed += change;

  };


  this.decelerate = function() {

    speed -= 5;

  };


  this.getSpeed = function() {

    return speed;

  };

};




map 方法可以方便的迭代数组,例子:

var timesFour = oldArray.map(function(val){

  return val * 4;

});


 map 方法会迭代数组中的每一个元素,并根据回调函数来处理每一个元素,最后返回一个新数组。注意,这个方法不会改变原始数组。

在我们的例子中,回调函数只有一个参数,即数组中元素的值 (val 参数) ,但其实,你的回调函数也可以支持多个参数,譬如:元素的索引index、原始数组arr

使用 map 方法来为 oldArray 中的每一项增加3,并且在 newArray 中保存它们。 oldArray 不应该被改变。




数组方法 reduce 用来迭代一个数组,并且把它累积到一个值中。

使用 reduce 方法时,你要传入一个回调函数,这个回调函数的参数是一个 累加器 (比如例子中的 previousVal) 和当前值 (currentVal)。

reduce 方法有一个可选的第二参数,它可以被用来设置累加器的初始值。如果没有在这定义初始值,那么初始值将变成数组中的第一项,而 currentVal 将从数组的第二项开始。

下面的例子使用了 reduce 来让数组中的所有值相减:

var singleVal = array.reduce(function(previousVal, currentVal) {

  return previousVal - currentVal;

}, 0);

使用 reduce 方法来让 array 中的所有值相加,并且把结果赋值给 singleVal




filter 方法用来迭代一个数组,并且按给出的条件过滤出符合的元素。

filter 方法传入一个回调函数,这个回调函数会携带一个参数,参数为当前迭代的项(我们叫它 val )。

回调函数返回 true 的项会保留在数组中,返回 false 的项会被过滤出数组。

下面的代码示例展示了使用 filter 来移除数组中值等于5的项:

 注意: 我们忽略了第二参数和第三参数,因为例子中我们只需要第一参数就够了。

array = array.filter(function(val) {

  return val !== 5;

});

使用 filter 来创建一个新数组,新数组的值是 oldArray 中值小于6的元素。不许改变原数组 oldArray




使用 sort 方法,你可以很容易的按字母顺序或数字顺序对数组中的元素进行排序。

与我们之前用的数组方法仅仅返回一个新数组不同, sort 方法将改变原数组,返回被排序后的数组。

sort 可以把比较函数作为参数传入。比较函数有返回值,当 a 小于 b,返回一个负数;当 a 大于 b ,返回一个正数;相等时返回0。

如果没有传入比较函数,它将把值全部转成字符串,并按照字母顺序进行排序。


下面的例子将展示 sort 的使用,传入的比较函数把元素按照从小到大的顺序进行排列:

var array = [1, 12, 21, 2];

array.sort(function(a, b) {

  return a - b;

});

使用 sort 按照从大到小的顺序排序 array



你可以使用 reverse 方法来翻转数组。

var myArray = [1, 2, 3];

myArray.reverse();

结果myArray 变成了 [3, 2, 1]

使用 reverse 来翻转 array 数组。并赋值给 newArray.



concat 方法可以用来把两个数组的内容合并到一个数组中。

concat 方法的参数应该是一个数组。参数中的数组会拼接在原数组的后面,并作为一个新数组返回。

下面是一个拼接数组的例子,用concatotherArray 拼接在 oldArray 的后面:

newArray = oldArray.concat(otherArray);

使用 .concat()concatMe 拼接到 oldArray 后面,并且赋值给 newArray




你可以使用 split 方法按指定分隔符将字符串分割为数组。

你要给 split 方法传递一个参数,这个参数将会作为一个分隔符。

下面的例子展示了 split 方法的使用,按照 s 字母进行分割:

var array = string.split('s');

使用 split 方法来把字符串 string 分割为数组 array

我们还可以使用 join 方法来把数组转换成字符串,里面的每一个元素可以用你指定的连接符来连接起来,这个连接符就是你要传入的参数。

下面展示了使用 join 来将数组中的每一项放入字符串,并用  and  进行连接:

var veggies = ["Celery", "Radish", "Carrot", "Potato"];

var salad = veggies.join(" and ");

console.log(salad); // "Celery and Radish and Carrot and Potato" 

使用 join 方法,连接符为' '把数组 joinMe 转化成字符串 joinedString.






1. Reverse a String 翻转字符串

具体步骤

  • 字符串->数组:str.split(“连接符”)
  • 翻转数组:arr.reverse(),本方法直接改变原数组
  • 数组->字符串:arr.join(“连接符”)

代码

function reverseString(str) {

  var arr = new Array();

  arr = str.split("");

  arr.reverse();

  str = arr.join("");

  return str;

}


reverseString("hello");  // olleh





2. Factorialize a Number 计算一个整数的阶乘

具体步骤

  • 分情况:if 判断 n=0n>0
  • 循环计算:n=0 时,n!=1n>0 时,循环累乘 n!=1×2×···×n

代码

function factorialize(num) {

  var sum = 1;

  if (num == 0) {

    sum = 1;

  }

  else {

    for (var i = 1; i <= num; i++) {

      sum = sum * i;

    }

  }

  return sum;

}


factorialize(5);  // 120





3. Check for Palindromes 判断回文

要求

回文(palindrome):一个字符串忽略标点符号、大小写和空格,正着读和反着读一模一样,例如 eye

如果给定的字符串是回文,返回 true,反之,返回 false

思路

去掉字符串多余的标点符号和空格,然后把字符串转化成小写,翻转之后检查是否与原字符串相等

具体步骤

  • 用正则表达式找到字符串多余的标点符号和空格(找出字母和数字即可)
  • 去除非字母数字符号:str.replace(被替换部分,替换部分)
  • 将字符串转为小写:str.toLowerCase()
  • 将字符串翻转:见第一题
  • 判断翻转后的字符串与原来的是否相同

正则表达式:用来匹配字符串中字符组合的模式。其中 W 表示字母、数字、下划线,因此 [\W_] 就可以表示非字母数字了,也可以用 [^A-Za-z0-9] 表示

代码

function palindrome(str) {

  var re = /[\W_]/g;

  var newStr = str.replace(re,"").toLowerCase();  // 纯字母数字的小写形式

  var reverseStr = newStr.split("").reverse().join("");

  return reverseStr == newStr;

}


palindrome("eye");  // true





4. Find the Longest Word in a String 找到提供的句子中最长的单词,并计算它的长度

思路

将字符串转为数组,记录下每个数组元素的长度,将长度排序

具体步骤

  • 将字符串转为数组:split()
  • 循环:将每个数组元素的长度保存在新数组中
  • 排序:将长度数组排序sort(),得到最大长度值

代码

function findLongestWord(str) {


  var arr = new Array();

  var arrLen = new Array();

  arr = str.split(" ");


  for (var i = 0; i < arr.length; i++){

    arrLen[i] = arr[i].length;

  }


  arrLen.sort(function(a,b) {

    return b-a;

  });


  return arrLen[0];

}


findLongestWord("The quick brown fox jumped over the lazy dog");  // 6




5. Title Case a Sentence 字符串的单词首字母大写其余小写

思路

先将所有字母统一为小写,再将字符串转化为数组,将每一个数组元素的第一个字符变为大写

具体步骤

  • 转小写:将字符串中所有字母转为小写 str.toLowerCase()
  • 字符串->数组:str.split()
  • 遍历数组,将每个数组元素第一个字母替换为大写
    遍历 arr.map()
    替换 arr.replace()
    单字符 arr.charAt(index)
    大写 toUpperCase()
  • 数组->字符串:arr.join()

代码

function titleCase(str) {


  str = str.toLowerCase();


  var arr = new Array();

  arr = str.split(" ");


  var newArr = new Array();

  newArr = arr.map(toUpper);

  function toUpper(element) {

    return element.replace(element.charAt(0),element.charAt(0).toUpperCase());

  }


  str = newArr.join(" ");

  return str;

}


titleCase("I'm a little tea pot");  // I'm A Little Tea Pot





6. Return Largest Numbers in Arrays 将小数组们的最大值串联成新数组

要求

大数组中包含了若干个小数组,分别找到每个小数组中的最大值(数值的最大值),然后把它们串联起来,形成一个新数组

具体步骤

  • 先把大数组分为若干小数组
  • 循环小数组中每一个元素
  • 找到每个小数组中的最大值
  • 用新数组存储最大值

代码

function largestOfFour(arr) {


  var newArr = new Array();


  for (var i = 0; i < arr.length; i++) {

    var max = arr[i][0];  // max 要定义在内层循环外

    for (var j = 0; j < arr[i].length; j++) {

      if (arr[i][j] >= max) {

    max = arr[i][j];

      }

    }

    newArr[i] = max;

  }

  return newArr;

}


largestOfFour([[4,5,1,3],[13,27,18,26],[32,35,37,39],[1000,10001,857,1]]);  // [5,27,39,10001]




7. Confirm the Ending 检查一个字符串是否以指定的字符串结尾

思路

首先要知道指定字符串 target 的个数,找到待检查字符串中最后几位,判断两者是否相等

具体步骤

str.substr(beginindex,endindex) 方法:返回字符串从指定位置开始,到指定长度的字符串

代码

function confirmEnding(str,target) {

  return target == str.substr(str.length-target.length,target.length);

}


confirmEnding("Bastian","n");  // true




8. Repeat a string repeat a string 重要的事情说3

要求

重复一个指定的字符串 num 次,如果 num 是一个负数则返回一个空字符串

具体步骤

  • 保留原始字符串:var newStr = str
  • 循环

代码

function repeat(str,num) {

  var newStr = str;

  if (num > 0) {

    for (var i = 0; i < num; i++) {

      newStr = newStr.concat(str);

    }

  }

  else {

    newStr = "";

  }

  return newStr;

}


repeat("abc",3);  // abcabcabcabc





9. Truncate a string 用瑞兹来截断对面的退路

要求

如果字符串的长度比指定的参数num长,则把多余的部分用来表示

切记,插入到字符串尾部的三个点号也会计入字符串的长度

但是,如果指定的参数num小于或等于3,则添加的三个点号不会计入字符串的长度

思路

最开始要判断 num 是否大于字符串长度,当 num 小于字符串长度时,分 num 小于等于 3 和大于 3 的情况,当 num<=3 时,直接在字符串后面加三个点;当 num> 3时,字符串 + 三个点的长度 =num

具体步骤

  • num<=3str.slice()str.concat(“…”)
  • num>3str.slice()str.concat(“…”)

代码

function truncate(str,num) {

  var newStr;

  if (num < str.length) {

    if (num <= 3) {

      newStr = str.slice(0,num);

      newStr = newStr.concat("...");

    }

    else {

      newStr = str.slice(0,num-3);

      newStr = newStr.concat("...");

    }

  }

  else {

    newStr = str;

  }

  return newStr;

}


truncate("A-tisket a-tasket A green and yellow basket","A-tisket a-tasket A green and yellow basket".length+2);  // A-tisket a-tasket A green and yellow basket





10. Chunky Monkey 猴子吃香蕉可是掰成好几段来吃哦

要求

把一个数组 arr 按照指定的数组大小 size 分割成若干个数组块

思路

将分割出的数组块当作一个个数组元素存在一个新的数组中,要确定分割的个数,才好循环

具体步骤

设定切割起始位置 begin end,并按照 size 大小累加,将切下的数组块循环 push 进新数组中

arr.slice(beginindex,endindex),切割时包括 beginindex,不包括 endindex

注意arr.push() 返回的是长度值

代码

function chunk(arr,size) {


  var newArr = new Array();

  var begin = 0;

  var end = size;


  for (var i = 0; i < arr.length/size; i++) {

    newArr.push(arr.slice(begin,end));

    begin = begin + size;

    end = end + size;

  }

  return newArr;

}


chunk(["a","b","c","d","e"],2);  // [["a","b"],["c","d"]["e"]]




11. Slasher Flick 打不死的小强

要求

返回一个数组被截断 n 个元素后还剩余的元素,截断从索引 0 开始(删除数组前 n 个元素)

具体步骤

array.splice(start, deleteCount[, item1[, item2[, …]]])

start 为开始索引值,deleteCount 为整数,表示要移出的元素个数,item1 表示要添加的元素,若无,则函数只删除元素。函数返回被删除元素数组

代码

function slasher(arr,howMany) {

  return arr.splice(howMany,arr.length-howMany);

}


slasher([1,2,3],2);  // [3]




12. Mutations 蛤蟆可以吃队友,也可以吃对手

要求

如果数组第一个字符串元素包含了第二个字符串元素的所有字符,忽略顺序和大小写,函数返回 true

例如:["hello", "hey"] 应该返回 false,因为字符串 "hello" 并不包含字符 "y"

再例如:["Alien", "line"] 应该返回 true,因为 "line" 中所有字符都可以在 "Alien" 找到

思路

首先要将两个字符串统一为小写,再看第二个字符串中的所有元素是不是都能在第一个字符串中找到

具体步骤

  • 数组->字符串:个数较少,直接用下标赋值
  • 字符串转小写:str.toLowerCase()
  • 第二个字符串->数组:str.split()
  • 检查第二个字符串中的每个字符是否都能在第一个字符串中找到

代码

function mutation(arr) {


  var str1 = arr[0].toLowerCase();

  var str2 = arr[1].toLowerCase();

  var arr2 = new Array();

  arr2 = str2.split("");


  for (var i = 0; i < arr2.length; i++) {

    if (str1.indexOf(arr2[i]) == -1) {

      return false;

    }

    else {

      continue;

    }

  }

  return true;

}


mutation(["hello","hey"]);  // false




13. Falsy Bouncer 真假美猴王

要求

删除数组中的所有假值

JavaScript中,假值有 falsenull0”“undefined NaN

思路

遍历数组,判断是否为假值,是则删除,否则留下

具体步骤

  • 遍历数组:arr.filter()
  • 判断是否为假值:Boolean(element)element 为假值返回 false,真值返回 true

代码

function bouncer(arr) {

  var newArr = arr.fliter(delFalsy);

  function delFalsy(element) {

    return Boolean(element);

  }

  return newArr;

}


bouncer([7,"ate","",false,9]);  // [7,”ate",9]


return arr.filter(Boolean);


14. Seek and Destroy 金克斯的迫击炮

要求

实现一个摧毁 destroyer 函数,第一个参数是待摧毁的数组,其余的参数是待摧毁的值

例如:destroyer([1, 2, 3, 1, 2, 3], 2, 3) 应该返回 [1, 1]

思路

遍历数组,将与待摧毁值相同的数组元素删除

具体步骤

  • 将待摧毁值存入一个数组中:arguments[index]
  • 遍历数组:arr.filter()
  • 判断是否要摧毁:循环+判断

注意

  • filter 是根据其函数返回值判断是否保留该元素,true 为保留,false 为删除。注意循环的结束与跳过情况
  • arguments[index] 不要放在内部函数中,这样将取不到外部函数的参数
  • 循环中最好不要调用函数

代码

function destroyer(arr) {

  var args = Array.prototype.slice.call(arguments, 1);


  return arr.filter(function(value){

    return !args.includes(value);

  });

}


destroyer([1, 2, 3, 1, 2, 3], 2, 3);


15. Where do I belong 我身在何处

要求

先给数组排序,然后找到指定的值在数组的位置,最后返回位置对应的索引

例如:where([1,2,3,4], 1.5) 返回 1

因为 1.5 插入到数组 [1,2,3,4] 后变成 [1,1.5,2,3,4],而 1.5 对应的索引值就是 1

具体步骤

  • 指定元素放入数组:arr.push()
  • 数组排序:从小到大 arr.sort()
  • 找到指定元素的索引:arr.indexOf()

代码

function where(arr,num) {

  arr.push(num);

  arr.sort(function(a,b) {

    return a-b;  // 从小到大

  });

  return arr.indexOf(num);

}


where([40,60],50);  // 1


16. Caesars Cipher 让上帝的归上帝,凯撒的归凯撒(凯撒编码)

要求

写一个 ROT13 函数,实现输入加密字符串,输出解密字符串。注意:所有的字母都是大写,不要转化任何非字母形式的字符(例如:空格,标点符号),遇到这些特殊字符,跳过它们

ROT13http://www.baike.com/wiki/ROT13&prd=so_1_doc

思路

A-M Unicode +13,将 N-Z Unicode -13

具体步骤

  • 得到字符串中每个字母的 Unicode(UTF16) 值:str.charCodeAt(index) 返回 0~65535 之间的整数
  • A-M Unicode +13,将 N-Z Unicode -13,其余字符不变
  • Unicode->字母:String.fromCharCode(Unicode)

代码

function rot13(str) {

  var arr = new Array();

  for (var i = 0; i < str.length; i++) {

    var utfNum = str.charCodeAt(i);


    if (utfNum >= 65 && utfNum <= 90) {

      if (utfNum <= 77) {

        utfNum += 13;

      }

      else {

        utfNum -= 13;

      }

    }


    arr[i] = String.fromCharCode(utfNum);

  }


  str = arr.join("");

  return str;

}


rot13("SERR CVMMN!"); // "FREE PIZZA!"

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值