JavaScript学习笔记

JavaScript面向对象编程指南练习题-第4章

2019-11-11  本文已影响0人  菜出意料

题目要求

在String()构造器不存在的情况下自定义一个MyString()的构造器函数。记住,由于String()不存在,因此您在写该构造器函数时不能使用任何属于内建String对象的方法和属性。并且要让您所创建的对象通过以下测试:

var s = new MyString('hello');
s.length
s[0]
s.toString()
s.valueOf()
s.charAt(1)
s.charAt('2')
s.charAt('e')
s.concat(' world')
s.slice(1, 3)
s.slice(0, -1)
s.slice('e')
s.split('e')
s.split('l')

思路

如果阅读过Java中String类源码,那么你就会自然而然的使用数组来解决该问题。

代码示例

function MyString(str) {
    var arr = [],
        index = 0;
    // 由于不能使用String的属性和方法,因此通过下标来将字符串中的每个字符放入数组中,并使用index变量记录字符串的长度
    while(!!str[index]) {
        arr.push(str[index]);
        index++;
    }

    // 使MyString对象可以通过下标访问每个字符
    for (var i=0; i<index; i++) {
        this[i] = arr[i];
    }

    this.length = index;

    this.toString = function() {
        return arr.join('');
    }

    this.valueOf = function() {
        return this.toString();
    }

    this.charAt = function(position) {
        // 转换为数字
        var idx = parseInt(position);
        // 如果是非数字
        if (isNaN(idx)) {
            return (index > 0 ? arr[0] : ''); // 如果字符串长度>0,返回第一个字符,否则返回''
        } else if (idx < 0 && idx >= index) { // 如果超出字符串的长度范围,则返回''
            return '';
        } else {
            return arr[idx];
        }
    }
    // 字符串拼接不会改变原有的字符串内容,仅返回新的字符串
    this.concat = function(s) {
        return this.valueOf() + s;
    }

    this.slice = function(s, e) {
        return arr.slice(s, e).join('');
    }

    this.split = function(c) {
        var start = 0, // 搜索起始位置
            idx = arr.indexOf(c), // 在数组中的位置
            splitArr = []; // 存放分割后的字符串
        // 如果数组中存在c
        while(idx !== -1) {
            // 将从start到idx之间的字符合并为字符串放入splitArr数组
            splitArr.push(arr.slice(start, idx).join(''));
            // 搜索起始位置移动到idx之后
            start = idx + 1; 
            idx = arr.indexOf(c,start);
        }

        // 字符串中检索不到c,并且搜索起始位置<数组最大的下标
        if (idx === -1 && start < index) {
            splitArr.push(arr.slice(start).join(''));
        }

        return splitArr;
    }
}
var s = new MyString('hello');
console.log('s.length:' + s.length);
console.log('s[0]:' + s[0]);
console.log('s.toString:' + s.toString());
console.log('s.valueOf:' + s.valueOf());
console.log('s.charAt(1):' + s.charAt(1));
console.log('s.charAt(\'2\'):' + s.charAt('2'));
console.log('s.charAt(\'e\'):' + s.charAt('e'));
console.log('s.concat(\' world\'):' + s.concat(' world'));
console.log('s.slice(1, 3):' + s.slice(1, 3));
console.log('s.slice(0, -1):' + s.slice(0, -1));
console.log('s.slice(\'e\'):' + s.slice('e'));
console.log('s.split(\'e\'):' + s.split('e'));
console.log('s.split(\'l\'):' + s.split('l'));
运行结果.png

以上仅为个人见解,仅起到抛砖引玉的作用,欢迎在评论区指出不足和改进建议。
在VSCode中直接运行js代码

上一篇 下一篇

猜你喜欢

热点阅读